Custom connectors let you push data from sources Adapter doesn’t natively integrate with — internal tools, legacy systems, anything you can hit with HTTPS. Instead of Adapter pulling on a schedule (the OAuth model), you push events whenever they happen, authenticated by an API key.Documentation Index
Fetch the complete documentation index at: https://docs.beta.adapter.com/llms.txt
Use this file to discover all available pages before exploring further.
When to use one
Reach for a custom connector when:- The source isn’t on the supported providers list.
- You already have an export pipeline and want Adapter to receive events directly.
- You want to mix first-party data (emails, pages, etc.) with synthetic events Adapter doesn’t otherwise see.
Creating a connector
Open the Console
Go to Connectors in app.adapter.com and switch to the Custom tab. Click Create connector.
Name it
Give it a display name and a source slug (auto-derived from the name, lowercase + hyphens). The slug is immutable after creation — it shows up in the event source (
custom:your-slug) and the storage path. Pick something descriptive.Pick accepted kinds
Select which first-party event types this connector may emit (
email, page, message, calendar, issue, or generic custom). Selecting none means all kinds are accepted. Anything outside the list is rejected with a 400.Pushing data
Each connector exposes four ingest endpoints under/v1/custom-connectors/{client_id}. All require Authorization: Bearer pk_live_….
Typed events (recommended)
Use the typed path when your data fits one of Adapter’s first-party shapes (email, page, etc.). Adapter applies the same processing as native connectors — entity extraction, relationship resolution, the works.
external_ids list — useful if you want to look up the resulting document later.
Plain text and arbitrary JSON
When your data doesn’t fit a typed shape — free-text notes, log lines, custom records from a tool that doesn’t have an Adapter integration — use the generic/ingest endpoint. It stores the data field verbatim as a StandardCustom event with event_type: "adapter.data.custom".
Free text:
data field accepts any JSON value — it’s stored as-is. There’s no required shape, but using a stable key (e.g. text, body, content) makes downstream queries easier.
Custom record with structure:
LLM enrichment does not run on
/ingest (JSON-only). If you have a long blob of text and want Adapter to extract summary/key-facts from it, save it to a file and post via /ingest/upload — the enricher picks up text/plain, PDFs, images, and Office docs.Binary uploads
For files (PDFs, images, Office docs), use the multipart upload endpoint:enriched_content block with summary, extracted text, and key facts. Use /ingest/upload (without /typed/) for binaries that don’t map to a typed kind.
Typed event shapes
Thepayload you send to /ingest/typed is validated against the corresponding type schema. Fields like source, user_id, container_id, and event_type are filled in automatically from the connector — you only supply the fields below. external_id is optional everywhere; Adapter generates one if you omit it. timestamp (ISO 8601) is also optional and defaults to ingest time.
email
| Field | Type | Required | Notes |
|---|---|---|---|
sender | string | ✓ | Display name or address. |
subject | string | ✓ | |
body_snippet | string | First few hundred chars of the body. Larger content goes through enrichment if attached as a binary. |
page
For documents — Notion pages, Confluence pages, internal wikis, PDFs uploaded as kind=page.
| Field | Type | Required | Notes |
|---|---|---|---|
title | string | ✓ | |
content_snippet | string | ||
url | string | Canonical link back to the source. | |
parent_id | string | Parent page/folder identifier. | |
parent_type | string | e.g. "folder", "page". | |
created_by | string | ||
last_edited_by | string | ||
last_edited_at | datetime | ISO 8601. |
message
For chat / Slack-like messages.
| Field | Type | Required | Notes |
|---|---|---|---|
channel_id | string | ✓ | |
sender | string | ✓ | |
text | string | ✓ | |
is_direct | boolean | ✓ | true for DMs, false for channels. |
thread_ts | string | Thread parent timestamp, if replying. |
calendar
| Field | Type | Required | Notes |
|---|---|---|---|
title | string | ✓ | |
start_time | datetime | Use for timed events. | |
end_time | datetime | ||
start_date | date | Use for all-day events. | |
end_date | date |
_time pair (timed) or the _date pair (all-day), not both.
issue
For tickets — Linear, Jira, GitHub issues, internal tracker rows.
| Field | Type | Required | Notes |
|---|---|---|---|
title | string | ✓ | |
number | integer | Display number (e.g. ENG-1234 → 1234). | |
description | string | ||
status | string | Free-form (e.g. "open", "in-progress"). | |
assignee | string | ||
priority | integer | ||
labels | array | List of label strings. | |
url | string | ||
action | string | One of "create", "update", "remove". |
custom
Escape hatch for data that doesn’t fit any typed shape. The whole data payload is stored verbatim.
| Field | Type | Required | Notes |
|---|---|---|---|
data | object | Any JSON. |
custom via the simpler /ingest endpoint (no kind field required) — see Generic events above.
Looking at ingested data
Each connector card in the console has a View Data button that expands to show document counts per resource. Counts update as data lands; if they ever drift, the recovery path is to re-ingest or contact support.Tips
external_idis optional — Adapter generates one if you omit it. Provide your own when you want idempotent re-ingest (re-posting the sameexternal_idoverwrites the document).metadataon the connector itself is attached to every event underraw._connector.metadata. Useful for tagging the source environment (e.g.{"env": "staging"}).- API key scope:
pk_live_…keys are tenant-scoped — one key works against any connector in your container. Rotate by creating a new key and revoking the old. - Deactivation stops new ingest but retains existing data.
What’s next
API reference
Full schema for the ingest endpoints.
Evidence types
The shape of typed first-party events.