Appearance
Receive Drip outcome callbacks
Preview contract
This guide follows the current Drip callback contract. Confirm rollout status with Dinodial before using it for a production campaign.
Drip sends a signed callback when a contact reaches a terminal outcome. This guide covers the complete integration: deploy a receiver, connect it to a process, place a rehearsal call, verify delivery, and recover callbacks that could not be delivered normally.
Prompt your AI agent
Recommendedtext
Use the `dino-pong` skill to connect and verify a Drip callback receiver.
Keep the callback secret out of chat, logs, source, and durable storage.
Verify raw-body signatures before parsing and persist by dd_pulse_id.
Return success only after durable storage.
For failed deliveries, read first and acknowledge only committed outcomes.
Ask for separate approval before every process, deployment, or call mutation.Use the Dino CLI directly
text
dino workspace current
dino workspace check
dino process failed-callbacks --help
dino process ack-failed-callbacks --helpThe callback receiver must:
- accept
POSTrequests over HTTPS; - use
X-Dinodial-Pulse-Process-Idonly to select the registered process key; - verify
X-Dinodial-Pulse-Signatureagainst the unmodified request body; - require the signed body's
process_idto match the process-ID header; - reject stale, future, malformed, or incorrectly signed requests;
- store each outcome idempotently using
dd_pulse_id; - return
2xxonly after durable persistence succeeds; and - keep the per-process callback secret outside source control and logs.
Callback lifecycle
- You create a Drip process and receive its callback secret once.
- You register the process and store its secret in your receiver's secret manager.
- Each inserted contact supplies the receiver's callback URL.
- Pulse sends one signed callback when the contact becomes terminal.
- Your receiver verifies and persists the outcome before returning
2xx. - If delivery fails, you reconcile it through the authenticated failed-callback API.
Terminal statuses include answered, busy, no-answer, DND, carrier failure, and platform failure. See Drip integration for the payload, status vocabulary, identity rules, HMAC wire contract, and reconciliation semantics.
Prepare your receiver
Use receiver code that your organization controls. Public documentation does not distribute a callback receiver source package. The installed dino-pong skill supplies Drip operations and recovery guidance, not receiver source.
Use these receiver components:
| Component | Purpose |
|---|---|
| HTTPS service | Accept callbacks and verify signatures |
| Secret manager | Store one callback secret for each process |
| Durable data store | Keep process registration and idempotent outcomes |
| Deployment operations | Build, test, deploy, inspect, and roll back the receiver |
Prerequisites
Prepare a receiver implementation that can preserve the unmodified request body, calculate HMAC-SHA256, compare values in constant time, and write durable state.
You also need:
- the current
dinoCLI configured for the intended workspace; - a published agent;
- a healthy Dino runtime;
- an outbound transport DID;
- a model-partner credential; and
- explicit approval before inserting a billable contact.
Verify the CLI and workspace before making changes:
sh
dino version check
dino capabilities
dino workspace current
dino workspace check
dino account get
dino catalog vox-servers
dino catalog transport-dids
dino catalog partner-credentialsVerify the receiver implementation
Test these cases before deployment:
- a valid signature and payload;
- body tampering;
- an incorrect process secret;
- a stale or future timestamp;
- malformed signature fields;
- a process-ID mismatch;
- duplicate delivery for one
dd_pulse_id; - a durable-store failure; and
- each supported terminal status.
Require all implementation-specific formatting, test, static-analysis, and production-build checks to pass.
Configure durable storage
Store process registration separately from callback outcomes. Keep callback secrets only in the secret manager.
For each accepted callback, store at least:
dd_pulse_idas the idempotency key;process_idandunique_idfor correlation;- the terminal status and complete accepted payload;
- the signature timestamp;
- the first acceptance time; and
- a duplicate count or equivalent duplicate-delivery evidence.
Use separate receiver and data-store deployments for production and non-production environments.
Deploy and preflight the receiver
Before each deployment mutation, verify the command directory, active account, exact service, data store, and expected effect. Obtain explicit approval for that mutation.
Deploy with your approved release procedure. Record the exact HTTPS callback URL and deployed version.
Confirm that the deployed receiver rejects an unsigned callback:
sh
curl -i \
-X POST \
-H 'Content-Type: application/json' \
--data '{}' \
<CALLBACK_HTTPS_URL>Expected status: 401 Unauthorized. The rejected request must not create a durable record.
Create the Drip process
Read the exact agent and infrastructure records before creating the process:
sh
dino agent get --agent-id <AGENT_GENESIS_UUID>
dino catalog vox-servers
dino catalog transport-dids
dino catalog partner-credentialsPreview the process name, region, agent, Dino runtime, transport DID, partner credential, VAD mode, timing, and retention settings for the approving operator. Then create exactly one running process:
sh
dino process create-drip \
--agent-id <AGENT_GENESIS_UUID> \
--name 'Callback tutorial drip' \
--region in \
--vox-server-id <HEALTHY_DINO_RUNTIME_UUID> \
--transport-did-id <OUTBOUND_DID_UUID> \
--partner-credentials-id <PARTNER_CREDENTIAL_UUID> \
--vad-mode <VAD_MODE> \
--lens-ttl-days <30-180> \
--hard-close-secs <90-900> \
--process-limit <1-255> \
--confirm-mutation process.drip.createChoose every value before approval. Confirm that process-limit fits the selected DID's available on-demand capacity. Idle prompts and timing come from the agent flow (lifecycleAudio.idle), not this command.
Use the agent genesis by default. Each new call then resolves the latest active version in that lineage. Supply an exact version ID only when the process must remain pinned to that version.
The response contains the process id and a one-time callbackSecret. The API key authenticates your Pulse requests. The callback secret authenticates Pulse's callback requests.
Configure the process in this order:
- Reserve a disabled registration for the process ID.
- Store
callbackSecretin the receiver's approved secret manager. - Map the process ID to the secret binding.
- Enable the registration only after the secret is available.
- Verify that receiver status output shows no secret value.
Never put callbackSecret in source control, shell history, screenshots, tickets, logs, or the durable data store.
Read the process back and confirm that it is running with zero contacts:
sh
dino process get --process-id <PROCESS_UUID>Place one rehearsal call
Create placeholders.json using the exact placeholders declared by the published agent:
json
{
"customer_name": "Taylor"
}Start the receiver's approved live deployment log before inserting the contact. Keep that log open.
In a second terminal, show the approving operator the exact phone number, process ID, process-scoped unique_id, placeholders, and callback URL. Inserting a contact is billable and begins dialing immediately.
After explicit approval for this exact destination and payload, insert one contact:
sh
dino process place-call \
--process-id <PROCESS_UUID> \
--unique-id tutorial-contact-0001 \
--phone +12025550123 \
--placeholders /absolute/path/to/placeholders.json \
--confirm-mutation process.drip.placeCall \
--callback-url <CALLBACK_URL>Persist the returned unique_id and dd_pulse_id. When the contact terminates, the live log must show a successful callback request without its body.
Use your receiver's authenticated operations to read the durable outcome. Verify the matching dd_pulse_id, process ID, unique ID, terminal status, signature timestamp, and duplicate-delivery evidence.
Verify that Pulse has no unacknowledged delivery failure:
sh
dino process failed-callbacks --process-id <PROCESS_UUID>An empty failures array means Pulse accepted the receiver's 2xx response. For answered calls, obtain the signed Lens review URL with:
sh
dino process list-calls --process-id <PROCESS_UUID>Interpret the evidence
| Evidence | What it proves |
|---|---|
| Receiver log reports a successful callback request | The deployed receiver handled a live request. |
| Durable storage contains the callback | The signature and schema passed before persistence. |
| Duplicate evidence reports one delivery | The receiver observed one delivery for that dd_pulse_id. |
| Pulse reports no failed callbacks | Pulse received a successful response from the receiver. |
Treat deployment logs as operational evidence, not callback storage. Define log retention and redaction before production use.
Recover failed deliveries
Do not rely only on normal webhook delivery. Periodically read the process's failed-callback queue through the authenticated Dino CLI, apply each terminal outcome idempotently using its dd_pulse_id, and acknowledge only the entries that were durably applied.
sh
dino process failed-callbacks --process-id <PROCESS_UUID>
dino process ack-failed-callbacks \
--process-id <PROCESS_UUID> \
--input /absolute/path/to/applied-failure-ids.json \
--confirm-mutation process.drip.failedCallbacks.ackNever acknowledge an entry before committing its outcome. A crash between acknowledgement and persistence would otherwise discard the recoverable copy.
Operate and update the receiver
Inspect the deployed version, secret bindings, outcome totals, and Pulse recovery queue:
sh
dino process get --process-id <PROCESS_UUID>
dino process failed-callbacks --process-id <PROCESS_UUID>Before you update the receiver:
- Run the implementation's complete verification suite.
- Validate the configured production artifact without publishing it.
- Show the exact target and expected effect for approval.
- Deploy one approved version.
- Repeat the unsigned-callback rejection check.
- Inspect the failed-callback queue during the observation period.
One receiver can support multiple concurrent processes when each process has a distinct encrypted secret binding. Keep the old binding while callbacks signed with that secret can still arrive.
Production checklist
- Use dedicated receiver and database deployments for each environment.
- Store the callback secret only in a secret manager.
- Keep only process registration metadata in the durable data store.
- Accept callbacks only over HTTPS.
- Verify the exact raw body before parsing JSON.
- Reject future and stale signatures and compare HMACs in constant time.
- Use
dd_pulse_idas the idempotency key. - Return
2xxonly after durable persistence succeeds. - Never log callback bodies or secrets.
- Monitor and reconcile the failed-callback queue independently of normal delivery.
- Decide whether persistent request logs are required and define redaction and retention first.
For the canonical payload, status vocabulary, signing rule, process-scoped identity model, and recovery contract, return to Drip integration.