SolidHooksSolidHooks
Get Started
Use casesAI agent webhook setup

Let an agent provision the whole pipeline

Every capability SolidHooks has is reachable over REST, documented in an OpenAPI spec and described again in plain prose written for models. What an agent cannot do is let itself in. You create the account and mint a key, choosing what that key reaches; from there the agent configures sources, destinations and connections, then reads back every event and delivery it produced.
One key, then unattendedOpenAPI + llms.txt600 requests/min per key
What this guide covers
  1. 01Why the account and the key are yours to create
  2. 02Minting a key and choosing what it reaches
  3. 03What a project-bound key can and cannot see
  4. 04Provisioning a pipeline in three calls
  5. 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.

You sign up
in the browser
You mint a key
scoped how you like
Agent gets the key
sdhk_sk_...
Pipeline live
REST, unattended
One handover, once per agent. From the key onward it runs without you.

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.

unbound keyTargets the oldest project by default. X-Project-Id selects another.
bound keyIgnores the header rules. No header targets the bound project, any other id returns 404.
/v1/projectsList returns only the bound project. Creating one returns 403.
rate limit600 requests per minute per key.

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.

curl
# 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.

curl
# 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"
Rejected-event logs are sampled
Those rows are rate limited per source, so under a flood the log is a representative sample rather than a complete ledger of every 401.

The machine-readable surface

  • /v1/spec.json is the OpenAPI 3 schema for every endpoint, and /v1 is the interactive reference over the same spec.
  • /llms.txt orients a model quickly. /llms-full.txt is the full walkthrough, including error semantics and the limits that bite.
  • Errors are typed rather than prose. QUOTA_EXCEEDED and RATE_LIMITED are distinct codes to branch on directly. Plan-limit errors such as a connector cap stay under FORBIDDEN, with a data payload (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=rejected before 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.