Skip to main content
Leads pushed with POST /v1/campaigns/{campaignId}/leads produce exactly one result each, once Pineyard has finished with the lead: automatic re-dials, callbacks and call analysis are all done. You can receive results by webhook, poll for them, or both.
Results are available for API campaigns in workspaces where results are enabled. Otherwise the result endpoints return 403 api_results_not_enabled. Contact Pineyard to enable them.

The result

Results are immutable: once created, a result never changes, even if the lead is called again by hand later. Results are kept for 90 days. Results don’t include the transcript or recording. Use data.finalCall.id with GET /calls/{id}.

Webhooks

Set up an endpoint

Webhook endpoints are created by a workspace admin in the Pineyard dashboard. API keys can list and delete endpoints but cannot create, change or verify them.
  • The URL must be https:// on port 443, with no credentials in it. Private network addresses are refused.
  • An endpoint can receive results from every API campaign, or only from chosen campaigns.
  • When the endpoint is created you get its signing secret (pyr_whsec_…). It is shown once.
  • The dashboard verifies the endpoint by sending a signed test event (type: "endpoint.test"). Your endpoint must reply 2xx. Results are delivered only for leads pushed after the endpoint was first verified. Changing the URL requires verifying again.
  • Up to 10 endpoints per workspace.

Request format

Pineyard sends a POST with the result as the JSON body and these headers:

Verify the signature

The signature is an HMAC-SHA256, keyed with your endpoint secret, of:
encoded as lowercase hex. Compute it over the raw bytes of the body, before any JSON parsing. Accept the request if any v1= value matches, and reject timestamps more than 5 minutes old to block replays.

Responding, retries and duplicates

  • Reply with any 2xx once you have stored the event. Do slow work afterwards; requests time out after 10 seconds.
  • These are retried: timeouts, network errors, 408, 425, 429 and 5xx. Retries come after 30 s, 2 min, 10 min, 1 h, 4 h, 12 h and 24 h: 8 attempts over about 41 hours, after which the delivery is marked dead.
  • A Retry-After header on a 429 sets the wait before the next attempt (between 1 second and 24 hours).
  • Any other response, including redirects (3xx) and other 4xx codes, fails the delivery immediately. Redirects are not followed.
  • Delivery is at least once and not ordered. De-duplicate on Pineyard-Event-Id.
  • Dead or failed deliveries can be redelivered from the dashboard. A redelivery sends exactly the same body.
  • Paused endpoints keep collecting results and send them when resumed.

Rotating the secret

When a workspace admin rotates the secret in the dashboard, both the new and the previous secret sign every request for 24 hours. Deploy the new secret within that window.

Delivery history

API keys with result_webhooks.view can read endpoints and delivery attempts: GET /result-webhooks/endpoints, GET /result-webhooks/deliveries (cursor-paginated) and GET /result-webhooks/deliveries/{id}.

Polling

Scope: campaigns.view. To catch up after downtime, page through GET /v1/results?createdAfter=<last result createdAt you stored>.