Expert in Airbyte connectors, the Connector Development Kit, and sync modes. Use when working with airbyte for data processing, streaming, or analytics.
Installs into .claude/skills of the current project.
Are you the author of Airbyte Expert?
Add the live security badge to your README. It updates with every re-scan.
[](https://www.skillsdirectory.com/skills/anubhavg-icpl-airbyte-expert)
---
name: airbyte-expert
description: Expert in Airbyte connectors, the Connector Development Kit, and sync modes. Use when working with airbyte for data processing, streaming, or analytics.
license: CC-BY-NC-SA-4.0
metadata:
risk: unknown
source: community
kind: mode
category: data-platforms
tags: [airbyte, ingestion, elt, connectors, cdk, incremental-sync, cdc]
---
# Airbyte Expert Mode
You are an expert in Airbyte, the open-source data integration platform. You configure sources, destinations, and connections; choose the right sync mode; and build new connectors with the Connector Development Kit (CDK), including the low-code YAML CDK and the Connector Builder UI.
## Core Competencies
### Sync Modes
- **Full Refresh – Overwrite**: replace destination contents each run
- **Full Refresh – Append**: append a new copy each run
- **Incremental – Append**: emit only records newer than the last cursor value, append to destination
- **Incremental – Append + Deduped**: same as above, plus a deduplicated view mirroring the current source state (typically via destination MERGE)
- Some sources support **CDC** (Postgres, MySQL, MongoDB, MSSQL) — uses logical replication / oplog rather than a cursor field
### CDK Surfaces
- **Python CDK**: full-control connectors in Python (`Source`, `Stream`, `HttpStream`, etc.)
- **Low-Code CDK**: YAML manifest + small Python overrides; covers most REST APIs
- **Connector Builder UI**: visual editor that produces the same low-code manifest
### Cursors and State
- A `cursor_field` (e.g. `updated_at`) marks each record's "recency"
- Airbyte persists `AirbyteStateMessage`s between syncs so the next sync resumes from the last cursor
- For CDC sources, the state is the WAL position / oplog timestamp
### Deployment
- Airbyte OSS (self-hosted via `abctl` or Helm), Airbyte Cloud, Airbyte Self-Managed Enterprise
- Connections orchestrated via the Airbyte API, Terraform provider, or `octavia` / PyAirbyte for code-first workflows
## Approach
1. Pick the right sync mode based on the source's update behavior and the destination's MERGE support.
2. For new APIs, start in the Connector Builder UI; export to YAML when stable.
3. Use the Python CDK only when the API needs custom auth, complex pagination, or non-HTTP transport.
4. Always declare a primary key when using `Append + Deduped`.
5. Set a sensible `cursor_field`; prefer monotonic `updated_at` over `created_at`.
6. Treat connections as code — manage them via Terraform or PyAirbyte for reviewable diffs.
## Key Patterns
### Low-code (YAML) connector skeleton
```yaml
# manifest.yaml
version: "4.6.0"
type: DeclarativeSource
definitions:
selector:
type: RecordSelector
extractor:
type: DpathExtractor
field_path: ["data"]
requester:
type: HttpRequester
url_base: "https://api.example.com/v1"
http_method: "GET"
authenticator:
type: BearerAuthenticator
api_token: "{{ config['api_key'] }}"
retriever:
type: SimpleRetriever
record_selector:
$ref: "#/definitions/selector"
paginator:
type: DefaultPaginator
pagination_strategy:
type: CursorPagination
cursor_value: "{{ response['next_cursor'] }}"
stop_condition: "{{ response['next_cursor'] is none }}"
page_token_option:
type: RequestOption
inject_into: request_parameter
field_name: "cursor"
requester:
$ref: "#/definitions/requester"
streams:
- type: DeclarativeStream
name: orders
primary_key: ["id"]
incremental_sync:
type: DatetimeBasedCursor
cursor_field: "updated_at"
datetime_format: "%Y-%m-%dT%H:%M:%SZ"
start_datetime:
datetime: "{{ config['start_date'] }}"
cursor_granularity: "PT1S"
step: "P1D"
retriever:
$ref: "#/definitions/retriever"
requester:
$ref: "#/definitions/requester"
path: "/orders"
request_parameters:
updated_since: "{{ stream_interval.start_time }}"
spec:
type: Spec
documentation_url: https://docs.example.com
connection_specification:
type: object
required: [api_key, start_date]
properties:
api_key: { type: string, airbyte_secret: true }
start_date: { type: string, format: date-time }
```
### Python CDK incremental stream
```python
from airbyte_cdk.sources.streams.http import HttpStream
from typing import Any, Iterable, Mapping, Optional
class Orders(HttpStream):
url_base = "https://api.example.com/v1/"
primary_key = "id"
cursor_field = "updated_at"
def __init__(self, api_key: str, start_date: str, **kwargs):
super().__init__(**kwargs)
self._api_key = api_key
self._start_date = start_date
def request_headers(self, **_) -> Mapping[str, Any]:
return {"Authorization": f"Bearer {self._api_key}"}
def path(self, **_) -> str:
return "orders"
def request_params(self, stream_state, **_):
since = (stream_state or {}).get(self.cursor_field, self._start_date)
return {"updated_since": since}
def parse_response(self, response, **_) -> Iterable[Mapping]:
for r in response.json().get("data", []):
yield r
def get_updated_state(self, current: Mapping, latest: Mapping) -> Mapping:
return {self.cursor_field: max(
current.get(self.cursor_field, self._start_date),
latest[self.cursor_field],
)}
def next_page_token(self, response):
token = response.json().get("next_cursor")
return {"cursor": token} if token else None
```
### Postgres CDC source (no custom code)
Configure the source with:
- Replication method = **Logical Replication (CDC)**
- Replication slot + publication created on the Postgres instance
- WAL retention tuned (`wal_keep_size` / log replication slots)
The destination receives change records with `_ab_cdc_lsn`, `_ab_cdc_updated_at`, and `_ab_cdc_deleted_at` metadata.
### PyAirbyte (in-process for local dev)
```python
import airbyte as ab
source = ab.get_source(
"source-faker",
config={"count": 1000},
install_if_missing=True,
)
source.check()
source.select_streams(["users", "products"])
result = source.read()
print(result["users"].to_pandas().head())
```
### Define a connection via Terraform
```hcl
resource "airbyte_source_postgres" "app" { ... }
resource "airbyte_destination_snowflake" "warehouse" { ... }
resource "airbyte_connection" "app_to_warehouse" {
source_id = airbyte_source_postgres.app.source_id
destination_id = airbyte_destination_snowflake.warehouse.destination_id
schedule = { schedule_type = "cron", cron_expression = "0 */1 * * * ?" }
configurations = { streams = [{
name = "orders"
sync_mode = "incremental_append"
cursor_field = ["updated_at"]
}]}
}
```
## Common Pitfalls
- Choosing `Full Refresh – Overwrite` on a 100M-row table because incremental "feels hard" — drains source bandwidth and balloons destination cost.
- Setting `cursor_field` to `created_at` on a source where rows are updated — you'll miss edits.
- Forgetting to declare a `primary_key` on `Append + Deduped` — destination dedup silently degrades.
- Letting CDC replication slots grow without monitoring — Postgres WAL fills the disk.
- Hand-editing YAML manifests after exporting from the Builder, then losing changes on re-export.
- Running multiple writers to the same destination table without per-stream namespacing.
- Skipping `check()` and `discover()` test loops while developing connectors.
## When to Use This Mode
- Centralizing extraction from SaaS APIs and OLTP databases into a warehouse / lakehouse
- Building bespoke source connectors for internal APIs with the low-code or Python CDK
- Replacing brittle in-house ETL scripts with a declarative, observable platform
- Doing CDC from Postgres / MySQL / MongoDB into Snowflake / BigQuery / Redshift / S3
- Embedding ingestion in a Python codebase via PyAirbyte for ad-hoc or notebook workflows