Public API Reference
Parsley's public REST API. Manage webhook subscriptions, verify auth, and receive real-time intent events from chatbot conversations.
Parsley exposes a small public REST API for managing webhook subscriptions and receiving real-time intent events. It is the same surface that powers the Zapier, Pabbly, Make, n8n, and Clay integrations - so anything those platforms can do, your own code can do too.
The model is event-driven: you create webhook subscriptions, Parsley POSTs events to your URL when things happen on your profile, you respond with a 2xx. There are no polling endpoints today.
Base URL
https://www.parsley.id/api/v1
All requests must use HTTPS. HTTP requests are rejected.
Authentication
Parsley uses long-lived API keys with the pk_live_ prefix. Generate one from Hub > API Keys in your dashboard. Keys are shown once at creation - store them in a secret manager.
Send the key on every request via the X-API-Key header:
curl https://www.parsley.id/api/v1/me \
-H "X-API-Key: pk_live_yourkeyhere"
For tools that prefer the OAuth-style header, Authorization: Bearer pk_live_... is also accepted.
Keys are scoped to the user and organisation that created them. Revoking a key from the UI takes effect on the next request.
Rate limits
100 requests per minute per API key. Exceeding it returns 429 Too Many Requests with these response headers:
X-RateLimit-Limit: 100
X-RateLimit-Remaining: 0
Retry-After: 60
Webhook deliveries from Parsley to your endpoints are not subject to this limit.
Event access
profile.viewed is available on all plans. The four high-signal events - chatbot.conversation.completed, lead.captured, lead.scored, signal.detected - require a paid plan or credit balance. Pricing is usage-based: 10¢ per AI conversation, no subscription. View pricing.
Anyone can create API keys and webhook subscriptions. A subscription that includes a high-signal event without a credit balance returns 403. The same gate applies at delivery time: events fired while you're out of credits are dropped silently rather than queued.
Endpoints
GET /me
Returns identity info for the authenticated key. Useful as an auth-test endpoint when wiring up a new client.
curl https://www.parsley.id/api/v1/me \
-H "X-API-Key: pk_live_yourkeyhere"
{
"userId": "user_abc123",
"email": "you@yourcompany.com",
"name": "Your Name",
"organisation": "Your Company",
"tier": "business",
"availableEvents": [
"profile.viewed",
"chatbot.conversation.completed",
"lead.captured",
"lead.scored",
"signal.detected"
]
}
POST /webhooks
Create a new webhook subscription. The secret field in the response is shown only once - store it for HMAC signature verification.
Body:
{
"url": "https://hooks.example.com/parsley",
"events": ["lead.scored", "signal.detected"]
}
Response (201):
{
"id": "sub_abc123",
"url": "https://hooks.example.com/parsley",
"events": ["lead.scored", "signal.detected"],
"secret": "whsec_a1b2c3...",
"active": true,
"createdAt": "2026-05-07T14:30:00Z"
}
GET /webhooks
List all active webhook subscriptions for the authenticated key. The full secret is not returned - only its prefix.
PATCH /webhooks/{subId}
Update a subscription's url, events, or active flag.
{ "active": false }
DELETE /webhooks/{subId}
Permanently delete a subscription.
POST /webhooks/{subId}/test
Send a synthetic event to your URL using the subscription's first registered event type. Use this to verify your endpoint is reachable and your signature verification is correct.
Webhook events
All events share the same envelope:
{
"id": "evt_abc123",
"type": "lead.scored",
"createdAt": "2026-05-07T14:30:00Z",
"data": { ... }
}
The five event types and their payloads are documented in detail in the Clay setup guide, the Zapier setup guide, and the Pabbly Connect guide. The shapes are identical across every consumer.
| Event | Access | Fires when |
|---|---|---|
profile.viewed | All plans | A visitor lands on your profile |
chatbot.conversation.completed | Paid/credits | A chatbot conversation ends |
lead.captured | Paid/credits | A visitor shares contact details |
lead.scored | Paid/credits | A lead receives a Hot, Warm, or Cold quality score |
signal.detected | Paid/credits | A MEDDIC buying signal is detected during a conversation |
lead.scored fires on every conversation turn after scoring. Filter on data.leadEmail != null if you only want enrichable rows.
Signature verification
Every webhook request includes these headers:
X-Parsley-Signature: sha256=<hex hmac>
X-Parsley-Event: lead.scored
X-Parsley-Delivery: evt_abc123
User-Agent: Parsley-Webhooks/1.0
The signature is HMAC-SHA256(rawRequestBody, subscription.secret) hex-encoded. Verify before trusting the payload:
import crypto from "crypto"
function verifyParsley(rawBody: string, header: string, secret: string) {
const provided = header.replace(/^sha256=/, "")
const expected = crypto.createHmac("sha256", secret).update(rawBody).digest("hex")
return crypto.timingSafeEqual(Buffer.from(provided), Buffer.from(expected))
}
Always compare the signature against the raw request body before any JSON parsing or middleware re-serialisation.
Delivery and retries
- Each delivery times out after 10 seconds.
- Non-2xx responses (or timeouts) are retried up to 3 times with exponential backoff: 1s, 5s, 30s.
- After 3 failures the delivery is marked failed and dropped. Persistent failures will be surfaced in Hub > API Keys in a future release.
- Deliveries are fire-and-forget from Parsley's side - your endpoint failing never blocks the chatbot or lead pipeline.
To stay reliable: respond 2xx immediately and process the payload asynchronously. Idempotency on your side keyed on id (the event ID) is the safest pattern - we may re-deliver after a transient failure.
Errors
| Status | Meaning |
|---|---|
| 200 | OK |
| 201 | Created |
| 400 | Validation error (see details in response) |
| 401 | Missing, malformed, or revoked API key |
| 403 | Event requires a paid plan or credit balance |
| 404 | Subscription not found (or not yours) |
| 429 | Rate limit exceeded |
| 500 | Server error - safe to retry |
Error responses always have this shape:
{ "error": "Invalid or revoked API key." }
Validation errors include a details object keyed by field name.
Use with Clay
A common pattern: use Clay HTTP columns to enrich a Parsley contact off the back of a webhook event. After your Clay table receives a lead.scored row, an HTTP column can call back into your own systems, or use the data.profileUserId to correlate.
For Clay-side setup (creating the webhook table and writing recipes against the events), see the Clay integration guide. The /api/v1 endpoints documented here are what you'd call from a Clay HTTP column for the rare reverse-direction case.
What's Next
- Zapier setup guide - point-and-click consumer of the same events
- Pabbly Connect setup - same events via webhook paste
- Clay integration - intent signals to enrichment to outbound
- All integrations - CRM and automation options
Questions? Contact us or email peter@parsley.id.
