Skip to content

Public routes: Email hooks

Where your mail provider posts replies, bounces and complaints, signed with the app’s inbound secret.

What it doesRoute
Bounces and complaints, for one appPOST /public/v1/apps/{key}/email-events
A reply by email, for one appPOST /public/v1/apps/{key}/inbound-email
Bounces and complaintsPOST /public/v1/email-events
A reply by emailPOST /public/v1/inbound-email

POST /public/v1/apps/{key}/email-events

Your mail provider’s bounces, complaints and deliveries, signed the same way. A hard bounce or a complaint puts the address on the app’s suppression list.

Needs: nothing: no credential.

Parameters

NameInDescription
key (required)pathThe app’s public key (app_…).
X-CRM-Signatureheadert=<unix seconds>,v1=<hex HMAC-SHA256 of “<t>.<body>”> under the inbound secret; refused more than five minutes from now.

Body (application/json): EmailEvent

FieldTypeDescription
address (always)string
detailstring
hardbooleanA bounce that is permanent; a soft one is counted and suppresses nothing.
id (always)stringThe provider’s id for the event: the same event posted twice is counted once.
kind (always)EmailEventKind (one of bounce, complaint, delivered)
message_id (always)string
occurred_at (always)string (date-time)

Answers

StatusBodyMeaning
202noneAccepted
400problemThe request could not be read: the problem names the field.
401problemNo credential, or one that is not right.
413problemToo large.
503problemNot set up here yet.

POST /public/v1/apps/{key}/inbound-email

Your mail provider’s inbound hook, through whatever turns its post into this shape and signs it with the app’s inbound secret (X-CRM-Signature). The reply is threaded into the user’s conversation.

Needs: nothing: no credential.

Parameters

NameInDescription
key (required)pathThe app’s public key (app_…).
X-CRM-Signatureheadert=<unix seconds>,v1=<hex HMAC-SHA256 of “<t>.<body>”> under the inbound secret; refused more than five minutes from now.

Body (application/json): InboundEmail

FieldTypeDescription
from (always)string
id (always)stringThe provider’s id for the message: the same message posted twice is threaded once.
received_at (always)string (date-time)
subjectstring
text (always)stringThe plain-text body, the quoted email under the reply still in it: PurrCRM keeps the reply alone.
to (always)array of string

Answers

StatusBodyMeaning
202objectAccepted
400problemThe request could not be read: the problem names the field.
401problemNo credential, or one that is not right.
413problemToo large.
503problemNot set up here yet.

POST /public/v1/email-events

The same events, signed with the deployment’s inbound secret.

Needs: nothing: no credential.

Parameters

NameInDescription
X-CRM-Signatureheadert=<unix seconds>,v1=<hex HMAC-SHA256 of “<t>.<body>”> under the inbound secret; refused more than five minutes from now.

Body (application/json): EmailEvent

FieldTypeDescription
address (always)string
detailstring
hardbooleanA bounce that is permanent; a soft one is counted and suppresses nothing.
id (always)stringThe provider’s id for the event: the same event posted twice is counted once.
kind (always)EmailEventKind (one of bounce, complaint, delivered)
message_id (always)string
occurred_at (always)string (date-time)

Answers

StatusBodyMeaning
202noneAccepted
400problemThe request could not be read: the problem names the field.
401problemNo credential, or one that is not right.
413problemToo large.
503problemNot set up here yet.

POST /public/v1/inbound-email

The same hook for a deployment whose reply addresses name the app themselves, signed with the deployment’s inbound secret.

Needs: nothing: no credential.

Parameters

NameInDescription
X-CRM-Signatureheadert=<unix seconds>,v1=<hex HMAC-SHA256 of “<t>.<body>”> under the inbound secret; refused more than five minutes from now.

Body (application/json): InboundEmail

FieldTypeDescription
from (always)string
id (always)stringThe provider’s id for the message: the same message posted twice is threaded once.
received_at (always)string (date-time)
subjectstring
text (always)stringThe plain-text body, the quoted email under the reply still in it: PurrCRM keeps the reply alone.
to (always)array of string

Answers

StatusBodyMeaning
202objectAccepted
400problemThe request could not be read: the problem names the field.
401problemNo credential, or one that is not right.
413problemToo large.
503problemNot set up here yet.