Let an agent provision the whole pipeline
- 01Why the account and the key are yours to create
- 02Minting a key and choosing what it reaches
- 03What a project-bound key can and cannot see
- 04Provisioning a pipeline in three calls
- 05Reading the record back when something goes wrong
The part that stays with you
An agent does nothing here until you hand it a key. Creating the account, verifying the owner's email and minting that key are browser steps, and keeping them that way is the point: the person who owns the billing relationship decides what the agent can reach, and the agent holds one credential you can see in a list and revoke in a click.
It also means there is no token juggling. The agent never touches an account endpoint, never holds a session, and cannot widen its own access. Everything it does runs on /v1/* with the key you gave it.
Minting a key and scoping what it reaches
In the dashboard under Organization → API Keys, New Key asks for a name, an optional expiry and Project access. Leave that on All projects and the key reaches everything in the organization. Pick one and the key is bound to it, which is how you keep an unattended run inside a blast radius you chose. The value appears once, so copy it straight into the agent's environment.
X-Project-Id selects another.The dashboard creates and revokes keys but does not re-scope them, so widening or narrowing a binding later means minting a replacement and retiring the old one. Per-key action permissions are planned; until they land, a key carries member-tier permissions — it reads everything in scope and creates, updates, toggles, retries and replays freely, while deletes, signing-secret reveal and rotation, mask rotation, connector provisioning and billing changes stay with an admin or owner in the dashboard.
Provisioning a pipeline
Three calls: a source to receive, a destination to send to, and a connection joining them. The source response carries the ingestUrl, which is the only thing your provider needs.
# Source. The ingestUrl is what your provider gets.curl -s "$API/v1/sources" -H "authorization: Bearer $SDHK_KEY" \ -H 'content-type: application/json' \ -d '{ "name": "Stripe", "provider": "stripe", "verifierConfig": { "secret": "whsec_..." } }'→ { "id": "src_...", "ingestUrl": "https://sdhk.events/<maskId>", ... } # Destination, then a connection joining the two.curl -s "$API/v1/destinations" -H "authorization: Bearer $SDHK_KEY" \ -H 'content-type: application/json' \ -d '{ "name": "Billing", "type": "http", "url": "https://acme.example/hooks" }' curl -s "$API/v1/connections" -H "authorization: Bearer $SDHK_KEY" \ -H 'content-type: application/json' \ -d '{ "name": "Stripe → Billing", "sourceId": "src_...", "destinationId": "dest_..." }'
Naming a known provider brings its signing scheme with it, so the agent supplies a secret rather than researching a signature format. Sources also accept inbound email, which the email guide covers.
Reading the record back
An agent that can only write is guessing. The same API returns every event with its verification result and every delivery with its attempts, which is what makes debugging an unattended run possible.
A signature failure returns a deliberately vague 401 to the caller, because explaining which check failed to an unauthenticated sender would turn the response into an oracle. The reason is recorded on the event instead, where an authenticated agent can read it.
# Why did nothing arrive?curl -s "$API/v1/events?status=rejected" -H "authorization: Bearer $SDHK_KEY"→ rejectionReason: "signature_mismatch" | "timestamp_out_of_tolerance" | ... # Re-send one failed delivery. Free, creates nothing new.curl -s -X POST "$API/v1/deliveries/dlv_.../retry" -H "authorization: Bearer $SDHK_KEY" # Run an event through its connections again. Billable.curl -s -X POST "$API/v1/events/evt_.../replay" -H "authorization: Bearer $SDHK_KEY"
The machine-readable surface
/v1/spec.jsonis the OpenAPI 3 schema for every endpoint, and/v1is the interactive reference over the same spec./llms.txtorients a model quickly./llms-full.txtis the full walkthrough, including error semantics and the limits that bite.- Errors are typed rather than prose.
QUOTA_EXCEEDEDandRATE_LIMITEDare distinct codes to branch on directly. Plan-limit errors such as a connector cap stay underFORBIDDEN, with adatapayload (limit,current) carrying the specifics instead.
Practices worth adopting
- Give each agent its own key. Revoking one then costs you nothing else, and the last-used column tells you which agent went quiet.
- Bind the key to a project unless the agent genuinely manages projects. It is the only scoping available today, and it cannot be changed after the key is minted.
- Branch on the error code, never on the message text. Messages are written for humans and the ingest 401 is intentionally uninformative.
- Check
?status=rejectedbefore re-sending anything. A signature that never verified will not verify on the second attempt either. - Prefer delivery retry over event replay when one consumer failed. Retry is free and replay is billed.
Questions
Hand your agent a key and let it build the pipeline
Mint a key, hand it over, and everything after that is an API call.