Scribble inbound hooks: send a card from any tool
For developers
Create an inbound hook under Integrations and POST the recipient’s details to its private URL. No bearer key is needed because the URL contains the credential. The hook stores a design, message template, sender and handwriting; the payload can override message and handwriting.
On this page
#Use a hook with an HTTP action
Every tool a customer already uses can POST JSON to a URL: Zapier, Make, n8n, a Salesforce Flow, a Shopify Flow action, a GitHub Action, four lines in their own backend. One URL that sends one card makes all of them work today, without an OAuth app per vendor that then has to be maintained.
#POST/api/v1/hooks/{token}
Send one handwritten card. The token in the URL is the credential.
No API key. The token in the URL is the credential.
Body parameters
| Field | Type | Description |
|---|---|---|
namerequired | string | Or first_name and last_name, which are joined. |
line1required | string | Also accepted as address1. |
line2 | string | Also accepted as address2. |
cityrequired | string | City. |
staterequired | string | Two-letter US state code. |
ziprequired | string | Also accepted as postal_code. Five digits, optionally with a +4. |
country | string | Defaults to US. |
message | string | The finished text. Required only if the hook has no message template. When both are present, message wins. |
handwriting | string | Handwriting name. Overrides the hook’s saved handwriting. If both are omitted, uses the space’s house handwriting. Unknown names return 422 unknown_handwriting. |
design_id | string | Overrides the hook's design. Takes the same two forms as a card send: one of your saved design ids, or card: and a slug from our full card collection. |
arrive_on | string | YYYY-MM-DD. The date the card should arrive by. |
reference | string | Also read from id. Echoed into your card history. |
curl -X POST https://scribblecards.com/api/v1/hooks/whk_YOURTOKEN \
-H "Content-Type: application/json" \
-d '{
"first_name": "Dana",
"last_name": "Okafor",
"line1": "88 Colin P Kelly Jr St",
"city": "San Francisco",
"state": "CA",
"zip": "94107",
"deal_name": "Q3 renewal",
"id": "deal_9931"
}'{
"id": "SC-2CR9793",
"object": "card",
"status": "scheduled",
"held_reason": null,
"arrives_between": {
"earliest": "2026-08-10",
"latest": "2026-08-14"
},
"url": "https://scribblecards.com/app/orders/SC-2CR9793"
}- Recipient fields may be at the top level or nested inside a
recipientobject. Both are read, so a flat Zapier field map works without a wrapper. - Any other field in the payload is available to the hook's message template. In the example above,
deal_namefilled{{deal_name}}. - The card written by that request read: Congratulations, Dana — everyone at Northwind is glad the Q3 renewal deal came through.
- The recipient is checked against this space’s do-not-mail list. Include
emailwhen opt-outs use email. A match returns422 recipient_suppressedand creates no card.
#Message templates
A hook's message template is what makes it usable from a tool with no text box. Fields come from the payload, plus {{first_name}} and {{full_name}} derived from the recipient, plus {{sender_name}} from the hook's Signed by setting.
Congratulations, {{first_name}} — everyone at
{{sender_name}} is glad the {{deal_name}} deal came
through.{
"error": {
"code": "template_incomplete",
"message": "This hook's message template needs deal_name, and the payload has no value for it. Send those fields, or send a finished `message` instead.",
"docs": "https://scribblecards.com/app/integrations"
}
}#GET/api/v1/hooks/{token}
Verification ping. Some tools fetch an endpoint before they will save it.
No API key. The token in the URL is the credential.
curl https://scribblecards.com/api/v1/hooks/whk_YOURTOKEN{
"object": "inbound_hook",
"ready": true,
"message": "This hook is live. POST a JSON body with a recipient to send a card.",
"example": {
"name": "Priya Raman",
"line1": "1 Fifth Avenue",
"city": "New York",
"state": "NY",
"zip": "10003",
"message": "Congratulations from all of us."
}
}- A
GETnever sends a card and never spends a credit. It exists because returning405here would fail some tools' setup wizards for no reason. - Note that a
GETreturnsready: truewithout checking the token, so it is not a way to test whether your token is correct. POST is.
#The token is the credential
| Status | Code | Cause |
|---|---|---|
| 401 | invalid_hook | The URL is wrong, or the hook was deleted. |
| 403 | hook_disabled | The hook was paused under Integrations. |
| 422 | invalid_recipient | A required address field is missing or malformed. |
| 422 | template_incomplete | The template needs a field the payload has no value for. |
| 422 | missing_message | No message and the hook has no template. |
| 402 | no_credits | The balance is empty. Nothing was created. |
#Named connectors
Scribble has public apps on Zapier and Make. The native HubSpot integration is deployed and available through a private pilot; it is not listed in HubSpot Marketplace. Shopify, Salesforce, Pipedrive and Zoho CRM do not have native Scribble marketplace listings yet. You can connect those platforms through Zapier or use an inbound hook with a workflow that can send an HTTP request.
#Common questions
- How many hooks can I have?
- As many as you want. One per trigger is the right shape, because each carries its own design, handwriting and message template, and each has its own fire count and log.
- Is a hook rate limited?
- Not by the API key limiter, because there is no key. One POST is still one card and one credit, so put the guard on your trigger.
- Can a hook send to more than one person?
- No. One POST, one card.
- How do I know a hook fired?
- The Integrations screen shows a fire count, a last-fired timestamp and a log of every call with its status and reason.
Last checked against the product on . Something wrong or missing? Tell us.
