Webhook transfer may not be available for your workspace yet. If it isn’t, the dashboard doesn’t show the
Webhook option, and the API refuses
transferMode: "WEBHOOK" with 400 transfer_webhook_unavailable. Contact
Pineyard to enable it.How it works
- During a call, the caller asks for a human.
- While the caller is on hold, Pineyard sends a signed
POSTto your URL with details of the call and contact, and the reason for the transfer. - Your endpoint replies
2xxwith{"to_number": "+919876543210"}before the timeout runs out. - Pineyard transfers the call to that number.
Turn it on for an agent
In the dashboard
Open the agent, go to Call transfer, turn transfer on and choose Webhook. Then set:- Webhook URL: your endpoint.
- Signing secret (optional, recommended): Pineyard uses it to sign every request. You can set, replace or remove it, but once saved it is never shown again.
- Timeout: how long Pineyard waits for your answer.
- Fallback number (optional): used when your endpoint has no answer. In webhook mode, this replaces the static transfer number.
With the API
The same settings are fields onPOST /agents and
PATCH /agents/{id} (scope agents.edit):
transferMode, transferWebhookUrl, transferWebhookTimeoutMs and
hasTransferWebhookSecret. The secret itself is never returned.
Validation errors:
Duplicating an agent copies its transfer settings, including the URL and the secret.
The request
The response
Reply with any2xx status and a JSON body containing the number to transfer to:
to_numbermust be one number in E.164 format with a leading+. Pineyard doesn’t guess a country code. Don’t send a list or alternatives (such as"+919876543210, +919876543211"or"+91... or +91...").- The answer must arrive within the agent’s
transferWebhookTimeoutMs. That budget also covers connecting to your server and Pineyard’s own processing of the call, so answer well inside it. Keep the response body small (under 16 KB). - Redirects aren’t followed.
- a non-
2xxstatus, a redirect, a timeout or a connection error - a body that isn’t JSON, or one with no
to_number, anullor emptyto_number, or ato_numberthat isn’t a valid number with a+ - a
to_numberthat contains more than one number, for example separated by,,/,;,|,ororand - a
to_numberthat is one of the two parties already on the call (the caller or the called number)
transferNumber if one is set. Otherwise the AI tells the caller
no one is available and keeps helping them. Pineyard never retries a transfer request.
If your workspace is suspended, Pineyard doesn’t call your endpoint at all. Transfers go straight to the fallback
number, as if no one were available.
To deliberately send a caller to the fallback number (for example, outside office hours), reply
200 {"to_number": null} or any non-2xx status.
Verify the signature
When the agent has a signing secret,X-Pineyard-Signature is v1= followed by the lowercase hex
HMAC-SHA256, keyed with your secret, of:
X-Pineyard-Signature isn’t sent. Set a secret for anything
beyond a quick test.
Requirements
- The URL must be
https://on port 443, with no username or password in it. - It must be reachable from the public internet. Pineyard won’t connect to private, loopback or link-local addresses, including through DNS. A URL that resolves to one of these is treated as no one available.
- Your endpoint must answer well within the timeout (500 to 4000 ms, 3000 ms by default), which also covers connecting and Pineyard’s own processing. Look up your routing data ahead of time or keep it cached, and don’t call slow services before replying.
Testing
- Set a fallback number before going live, so a slow or failing endpoint still reaches a person.
- Use a test call or a web session from the dashboard, and ask the agent to speak to a person.
- Log the raw body and headers of the first few requests, and check that your signature check accepts them before you start rejecting unsigned or invalid requests.
- To test the fallback, temporarily return
503or{"to_number": null}: the call should go to the fallback number, or, without one, the agent should apologise and carry on. - A tunnelling tool that gives you a public
https://URL works for local development. Make sure it answers well within the timeout.

