Webhooks

Send events from any external system into your Ploy workspace, write them to PloyDB, and trigger Ploybooks automatically.

Ploy webhooks are inbound: external systems (Clay, Stripe, Zapier, your own backend, partner APIs) POST events to a per-endpoint URL in your workspace. Each accepted event is stored, searchable, and can optionally run a Ploybook with the event payload as prompt context.


How It Works

  1. Create an endpoint in Workspace Settings → Webhooks. Ploy mints an ingest URL and an API key.
  2. Configure the sender (Clay, Stripe, your backend) to POST JSON to the ingest URL with your API key in the Authorization header.
  3. (Optional) Wire a Ploybook trigger so every accepted event runs a workflow with the payload as context.
  4. Inspect events in the dashboard or by asking Ploy's Agent — every received event is stored with its full payload.

Tip: Endpoints are scoped to a workspace, not a site — one endpoint can drive workflows that touch multiple sites.


Creating an Endpoint

  1. Open Workspace Settings → Webhooks.
  2. Click New endpoint and give it a description (e.g. Clay enrichment or Stripe events).
  3. Ploy mints the endpoint and shows its API key once. Copy it now — it can't be retrieved later. If lost, rotate the endpoint and reconfigure the sender.
  4. Copy the ingest URL. It has the shape:
https://ploy.ai/api/v1/webhook/{endpointSlug}

Tip: You can also ask Ploy's Agent — "Create a webhook endpoint for Clay enrichment." Ploy's Agent will surface the URL and key in chat.


Authentication

Send the API key as a bearer token in the Authorization header on every request:

Authorization: Bearer {apiKey}
  • Requests without a valid key are rejected with 401 Unauthorized.
  • Keys are scoped to a single endpoint. Disabling or rotating an endpoint invalidates its key immediately.
  • Treat keys like passwords. Store them in your sender's secret manager — never commit them to source control.

Sending Events

Send an HTTP POST with a JSON body to the ingest URL:

curl -X POST https://ploy.ai/api/v1/webhook/ENDPOINT_SLUG \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "event": "lead.enriched",
    "email": "alex@acme.com",
    "company": "Acme Inc.",
    "title": "VP Marketing"
  }'

Request Format

FieldRequirement
MethodPOST only.
Content-Typeapplication/json. Other content types are rejected with 415.
BodyAny well-formed JSON object. Schema is up to you — Ploy stores the payload verbatim.
Payload sizeUp to 1 MB. Larger payloads return 413 Payload Too Large.
AuthAuthorization: Bearer {apiKey} required on every request.

Response Codes

StatusMeaning
202 AcceptedEvent stored. If a Ploybook trigger is wired, it's queued asynchronously.
400 Bad RequestBody is not valid JSON.
401 UnauthorizedMissing or invalid Authorization header.
403 ForbiddenEndpoint is paused or disabled.
404 Not FoundEndpoint slug doesn't exist.
413 Payload Too LargeBody exceeds 1 MB.
415 Unsupported Media TypeContent-Type is not application/json.
429 Too Many RequestsEndpoint is being rate limited. Back off and retry.

Sender Retry Guidance

Ploy returns 202 Accepted as soon as the event is stored. If you get a non-2xx response, the event wasnot stored — your sender should retry with exponential backoff. Most sources (Clay, Stripe, Zapier) handle this automatically. For custom backends, retry on 5xx and 429 with jitter; do not retry on 4xx other than 429.


Triggering a Ploybook

The most powerful pattern is wiring an endpoint to a Ploybook. Every accepted event runs the Ploybook with the payload injected as prompt context — so a webhook becomes a workflow trigger.

  1. Create the Ploybook you want to run (e.g. Generate ABM page for prospect).
  2. In Workspace Settings → Webhooks, open the endpoint and set Ploybook trigger to your Ploybook.
  3. Each future event runs that Ploybook in the background. Pass null to clear the trigger and go back to store-only mode.

Tip: Just ask Ploy's Agent — "Trigger the Generate ABM page for prospect Ploybook on the Clay endpoint." It'll wire it up.


Writing Webhook Data to a PloyDB Table

A webhook endpoint stores every accepted event in webhook history. To also create or update a record in a PloyDB table, connect the endpoint to a Ploybook that validates the payload and writes the mapped values to the table.

  1. Create a webhook. Go to the workspace settings page for Webhooks and either create a webhook or select an existing one.
  2. Copy the curl command below and update it based on the data you plan on mapping:
    curl -X POST "https://ploy.ai/api/v1/webhook/[webhook_id]" \
      -H "Authorization: Bearer [webhook api key]" \
      -H "Content-Type: application/json" \
      --data '{"hello":"world"}'
  3. Send one test event using the curl command with a realistic shape of data. Confirm the webhook accepts the event before connecting it to PloyDB.
  4. Attach the webhook to the PloyDB instance you created. Open the webhook in Workspace Settings → Webhooks and select the PloyDB instance as its destination.
  5. Send another test event. Run the updated curl command again to ensure everything is working properly, then open PloyDB and confirm that the expected data exists in the table.
{
  "event": "lead.created",
  "event_id": "evt_01JABC123",
  "email": "alex@acme.com",
  "company": "Acme Inc.",
  "title": "VP Marketing",
  "received_at": "2026-09-03T14:30:00Z"
}
Payload fieldPloyDB columnWrite behavior
event_idEvent IDUse as the unique match key for an upsert.
emailEmailValidate before writing.
companyCompanyWrite as text.
titleTitleWrite as text when present.
received_atReceived atWrite as a date and time.

Tip: Include a stable event ID and use an upsert instead of an unconditional insert. If the sender retries the same event, the Ploybook updates the existing record instead of creating a duplicate.

Keep credentials out of the payload. The external sender only needs the webhook endpoint's API key; Ploy handles the connection to the attached PloyDB instance.


Example: Clay Enrichment → ABM Landing Page

A high-leverage setup: Clay enriches a list of target accounts, posts each enriched row to Ploy, and Ploy runs a Ploybook that generates a personalized ABM landing page for the prospect — pre-loaded with their company name, industry, and pain points. Drop the URL into your outbound sequence so every prospect lands on a page built for them.

1. Create the endpoint

In Workspace Settings → Webhooks, create an endpoint described as Clay enrichment. Copy the URL and key.

2. Configure Clay

In your Clay table, add an HTTP API action:

  • Method: POST
  • URL: https://ploy.ai/api/v1/webhook/{endpointSlug}
  • Headers: Authorization: Bearer YOUR_API_KEY · Content-Type: application/json
  • Body: a JSON object referencing Clay's enriched columns. Press / inside the Body field to open Clay's column picker and insert the right field — Clay wraps each one in a typed token so the value flows through on every run.
{
  "event": "clay.account_enriched",
  "company": "{{company}}",
  "company_domain": "{{domain}}",
  "industry": "{{industry}}",
  "headcount": "{{headcount}}",
  "tech_stack": "{{tech_stack}}",
  "recent_news": "{{recent_news}}",
  "primary_contact_first_name": "{{first_name}}",
  "primary_contact_title": "{{title}}"
}
Clay HTTP API action configured to POST enriched account data to a Ploy webhook endpoint, with Method set to POST, the Ploy ingest URL in Endpoint, a JSON Body referencing Clay columns, and an Authorization Bearer header.
Clay's HTTP API action — Method, Endpoint, Body with column tokens, and Authorization header.

3. Wire the Ploybook

Build a Ploybook called Generate ABM page for prospect with steps like: clone your ABM page template → rewrite the hero, value props, and social proof to match the prospect's industry and recent news → publish at a unique slug like /for/{company-slug} → return the URL. Set this Ploybook as the trigger on the Clay endpoint.

4. Run Clay & sequence the URL

Each row Clay sends fires the Ploybook with the full payload as context. Pages publish within a couple of minutes — write the published URL back to a Clay column, then reference it in your outbound copy (e.g. {{abm_page_url}}) so every prospect clicks through to a page built for them.

Tip: Test with a single Clay row first. Watch the event land in Workspace Settings → Webhooks → Events, confirm the Ploybook run finishes successfully, and review the generated page before turning Clay loose on the full account list.


Inspecting Received Events

Every accepted event is stored with its full payload, timestamp, and source endpoint. You can:

  • Browse events in Workspace Settings → Webhooks → Events — filter by endpoint, time range, or substring search across the payload.
  • Click into any event to see the full request body and the resulting Ploybook run (if a trigger is wired).
  • Ask Ploy's Agent — "Show me the last 10 events on the Clay endpoint" or "Find webhook events containing alex@acme.com." Ploy's Agent queries event history directly.

Pausing & Rotating Endpoints

  • Pause — Disable an endpoint to immediately stop accepting events. Senders receive 403 Forbidden. Re-enable any time.
  • Resume — Re-enables event acceptance. Existing API keys stay valid.
  • Rotate — If a key leaks, create a new endpoint, update the sender, then disable the old one. Keys are shown once and can't be retrieved.
  • Delete — Permanently removes the endpoint and its event history.

Tip: When debugging a flaky sender, pause the endpoint instead of deleting it — paused endpoints preserve all prior events and can be resumed without reconfiguring the sender.


Limits & Behavior

PropertyValue
Payload size1 MB max per request.
Content typeapplication/json only.
MethodsPOST only.
AuthAuthorization: Bearer {apiKey} required on every request.
StorageEvery accepted event is stored with its full payload, timestamp, and endpoint.
Ploybook executionRuns asynchronously after 202 Accepted is returned. Failures are logged on the event detail view.
RetriesSender-driven. Ploy does not retry inbound events — your sender should retry on 5xx and 429.

Troubleshooting

  • 401 Unauthorized — Check the Authorization header. It must be Bearer {apiKey} with a single space and no quotes around the key.
  • 403 Forbidden — Endpoint is paused. Re-enable in Workspace Settings → Webhooks.
  • 404 Not Found — The endpoint slug in the URL doesn't exist or was deleted. Confirm the URL matches the one shown on the endpoint detail page.
  • 413 Payload Too Large — Trim the body below 1 MB. For bulk loads, send one event per row instead of batching.
  • 415 Unsupported Media Type — Set Content-Type: application/json. Form-encoded and multipart bodies are not accepted.
  • Ploybook didn't run — Confirm the trigger is set on the endpoint and the Ploybook itself isn't disabled. Check the event detail view for the run status and any error.
  • Lost the API key — Keys are shown once. Create a new endpoint, update the sender, and disable the old one.

What's Next?

  • Store structured records — Read the PloyDB guide to create tables and manage the records your webhook workflow writes.
  • Build the workflow — Read the Ploy's Agent & Ploybooks guide to design the Ploybook your endpoint will trigger.
  • Connect more tools — See the Integrations directory for first-class connections (HubSpot, Notion, GitHub, and more).
  • Review security — How Ploy protects your data is covered in Security & Compliance.
  • Get help — Check the FAQ & Troubleshooting page or email support@ploy.ai.