The http adapter sends a JSON webhook request to a service you control. Use it when the runtime is remote, long-lived, or already exposed as an API instead of a local command.
Info:
httpis a built-in internal adapter used by Paperclip's runtime. It's currently shown as "Coming soon" in the agent-config adapter-type dropdown and can't be selected manually. To target it today, configure the agent via the API or an imported company export.
- The agent runs in the cloud or behind another service.
- You want Paperclip to trigger a webhook and let the remote service do the rest.
- The runtime already expects a JSON body and returns a simple success or failure response.
- The runtime is just a local script or command. Use Process.
- You need session persistence or built-in CLI behavior. Use one of the local adapters instead.
- You need Paperclip to parse a rich stdout transcript from the remote runtime.
| Field | Required | Notes |
|---|---|---|
url |
yes | Absolute http:// or https:// endpoint. |
method |
no | HTTP method to use. Defaults to POST. |
headers |
no | Extra request headers. |
payloadTemplate |
no | JSON object merged into the request body before the standard Paperclip fields are added. |
timeoutMs |
no | Request timeout in milliseconds. 0 means no timeout. |
Note: The HTTP adapter does not run a child process. It sends a single request, waits for the response, and treats any non-2xx response as a failure.
Paperclip sends a JSON payload that always includes:
runIdagentIdcontext
Any payloadTemplate fields are merged in first, then Paperclip adds the standard fields above. If a key collides, the standard Paperclip field wins.
Example body shape:
{
"runId": "run-123",
"agentId": "agent-123",
"context": {
"taskId": "issue-123",
"wakeReason": "scheduled",
"commentId": null
},
"customField": "value"
}Your service uses the Paperclip API base URL and a long-lived agent API key to call back into the control plane after it finishes — see Authentication below.
The HTTP adapter has two distinct authentication directions, and both matter:
1. Paperclip → your service. Paperclip needs to prove the webhook came from you. Use a shared secret in headers:
{
"headers": {
"Authorization": "Bearer <shared-secret>",
"X-Webhook-Secret": "<another-shared-secret>"
}
}Verify the header server-side and reject anything that doesn't match. If you want signature verification instead, sign the canonical body with HMAC-SHA256 in your payloadTemplate and verify on the receiver.
2. Your service → Paperclip. After the webhook fires, your service typically needs to post comments, update the issue, or mark it done. That is a separate authentication step — Paperclip does not auto-inject a JWT into a remote service the way it does for local adapters.
Mint a long-lived agent API key once and store it as a secret in your service:
pnpm paperclipai agent api-key create <agent-id> --company-id <company-id>That signs an agent JWT with the server's PAPERCLIP_AGENT_JWT_SECRET and prints the bearer string. Use it as Authorization: Bearer <token> on every callback. Always include X-Paperclip-Run-Id: <runId-from-webhook> so the audit log attributes your changes to the run that triggered them.
Note:
PAPERCLIP_AGENT_JWT_SECRETlives only on the Paperclip server. Your remote service never sees the secret — it receives the signed token created bypaperclipai agent api-key create.
Idempotency. Webhooks should be safe to retry. If your remote service accepts the request but later fails to call back, Paperclip cannot tell the difference. Make the receiver idempotent on runId, and prefer to acknowledge with 2xx as soon as the request is durably queued, not after all follow-up work completes.
The Test Environment button checks:
- The URL is present and uses
httporhttps. - The configured method is valid.
- The endpoint responds to a quick
HEADprobe when reachable.
If the probe fails in a private network, that can still be acceptable. The important part is whether the runtime can actually receive the production request.
{
"adapterType": "http",
"adapterConfig": {
"url": "https://agent.example.com/paperclip/heartbeat",
"method": "POST",
"headers": {
"Authorization": "Bearer <shared-secret>"
},
"payloadTemplate": {
"source": "paperclip"
},
"timeoutMs": 10000
}
}- Use a shared secret or header-based auth on the remote service.
- Keep the endpoint idempotent when possible because retries are easier to support.
- Return a 2xx response when the webhook was accepted, not when all follow-up work is complete.