Create a key in your portal
Open Integrations in your portal and create an API key, giving it a label such as the name of the CRM that will hold it. The key is shown once, so paste it straight into the platform that will use it.
The details of every family you serve already live in the CRM your team works in each day, and the handwritten cards can follow from there. Connect it once, and each family is enrolled at the moment your staff records them, with nothing further to re-enter.
and any platform that can send a webhook
Open Integrations in your portal and create an API key, giving it a label such as the name of the CRM that will hold it. The key is shown once, so paste it straight into the platform that will use it.
Add a webhook or an automation step in your CRM that posts the family details to the intake endpoint, with the key in the Authorization header. The guides below cover each platform step by step.
As soon as your automation fires, the family appears in your portal with the CRM named as the source, and the handwritten cards follow the schedule from there, mailed under your own name.
Each guide assumes your key is already on the clipboard. Field names come from the reference further down, and any field your CRM does not hold can be left out as long as the required ones are present.
Body for Webhooks by Zapier
{
"recipientName": "Margaret Ellison",
"addressLine1": "418 Oak Street",
"city": "Cedar Rapids",
"state": "IA",
"postalCode": "52402",
"relationship": "wife",
"subjectName": "David Ellison",
"dateOfPassing": "2026-03-14",
"externalId": "12345",
"externalSource": "zapier"
}Custom request body
{
"recipientFirstName": "{{ contact.firstname }}",
"recipientLastName": "{{ contact.lastname }}",
"recipientEmail": "{{ contact.email }}",
"addressLine1": "{{ contact.address }}",
"city": "{{ contact.city }}",
"state": "{{ contact.state }}",
"postalCode": "{{ contact.zip }}",
"relationship": "{{ contact.relationship_to_deceased }}",
"subjectName": "{{ contact.deceased_name }}",
"dateOfPassing": "{{ contact.date_of_passing }}",
"externalId": "{{ contact.hs_object_id }}",
"externalSource": "hubspot"
}Sample request body for the callout
{
"recipientName": "Margaret Ellison",
"addressLine1": "418 Oak Street",
"addressLine2": "Apt 2",
"city": "Cedar Rapids",
"state": "Iowa",
"postalCode": "52402-1183",
"recipientEmail": "[email protected]",
"relationship": "wife",
"subjectName": "David Ellison",
"dateOfPassing": "2026-03-14",
"externalId": "0035g00000AbCdEfGHI",
"externalSource": "salesforce"
}Raw JSON body with merge fields
{
"recipientName": "${Contacts.Full Name}",
"addressLine1": "${Contacts.Mailing Street}",
"city": "${Contacts.Mailing City}",
"state": "${Contacts.Mailing State}",
"postalCode": "${Contacts.Mailing Zip}",
"relationship": "${Contacts.Relationship}",
"subjectName": "${Contacts.Deceased Name}",
"dateOfPassing": "${Contacts.Date of Passing}",
"externalId": "${Contacts.Contact Id}",
"externalSource": "zoho"
}JSON body with merge tags
{
"recipientFirstName": "{{contact.first_name}}",
"recipientLastName": "{{contact.last_name}}",
"recipientPhone": "{{contact.phone}}",
"addressLine1": "{{contact.address1}}",
"city": "{{contact.city}}",
"state": "{{contact.state}}",
"postalCode": "{{contact.postal_code}}",
"relationship": "{{contact.relationship}}",
"subjectName": "{{contact.deceased_name}}",
"dateOfPassing": "{{contact.date_of_passing}}",
"externalId": "{{contact.id}}",
"externalSource": "highlevel"
}Fields the Create Recipient action sends
{
"recipientName": "Margaret Ellison",
"addressLine1": "418 Oak Street",
"city": "Cedar Rapids",
"state": "IA",
"postalCode": "52402",
"relationship": "wife",
"subjectName": "David Ellison",
"dateOfPassing": "3/14/2026",
"externalId": "98765",
"externalSource": "followupboss"
}Every request carries your key in an Authorization header.
Authorization: Bearer lak_9f3d2c7b8a1e5406d2f7c9b3a8e1450d6f2c7b93Keys are created in your portal under Integrations, they are shown once at the moment you create them, and any key can be revoked from the same page if a laptop walks off or a staff member moves on. A key acts for your whole account, so keep it in the credential store of the platform that uses it and away from email and shared documents.
The base URL is https://api.lastingaftercare.com and both endpoints accept the same key.
GET /v1/integrations/me Confirms a key works and returns the account it belongs to. POST /v1/integrations/intake Creates a recipient and starts the year of cards.
Unknown keys in the body are ignored, so a CRM may post its whole record and let us take
the fields we recognize. Teams that prefer the full nested contract can keep using
POST /v1/cases with the same key.
Retries are safe. When your platform can send your record id as
externalId, a repeat of the same id returns the original recipient. When it
cannot, you may send an Idempotency-Key header of 8 to 128 characters that
stays the same across retries, and without either we treat an identical body as the same
request.
| Field | Required | Notes |
|---|---|---|
recipientName | Required | The person who receives the cards. You may send recipientFirstName and recipientLastName instead. |
recipientFirstName | Optional | Paired with recipientLastName, this stands in for recipientName. |
recipientLastName | Optional | Paired with recipientFirstName, this stands in for recipientName. |
addressLine1 | Required | Street address. |
addressLine2 | Optional | Apartment, suite, or unit. |
city | Required | Mailing city. |
state | Required | Two-letter code or the full state name, in any case. |
postalCode | Required | ZIP or ZIP+4, with or without the hyphen. |
country | Optional | The United States for now, so leave it out, or send US, USA or United States. |
recipientEmail | Optional | Used for your records, never for marketing. |
recipientPhone | Optional | Ten digits, eleven with the leading one, or E.164. |
relationship | Optional | Free text such as wife, son, or pet parent. Anything we do not recognize is recorded as other. |
subjectName | Required | The person, resident, patient or pet the cards honor. |
dateOfPassing | Required | YYYY-MM-DD, an ISO datetime, M/D/YYYY, or epoch milliseconds. |
dateOfBirth | Optional | Same formats as dateOfPassing. |
serviceDate | Optional | Same formats as dateOfPassing. |
religion | Optional | Guides the wording chosen for the family. |
notes | Optional | Anything your team wants on the case. |
externalId | Optional | Your record id. A repeat with the same id returns the original recipient instead of creating another. |
externalSource | Optional | A short label such as hubspot or zoho, shown beside the family in your portal. |
curl -X POST https://api.lastingaftercare.com/v1/integrations/intake \
-H "Authorization: Bearer lak_your_key_here" \
-H "Content-Type: application/json" \
-d '{
"recipientName": "Margaret Ellison",
"addressLine1": "418 Oak Street",
"city": "Cedar Rapids",
"state": "IA",
"postalCode": "52402",
"relationship": "wife",
"subjectName": "David Ellison",
"dateOfPassing": "2026-03-14",
"externalId": "12345",
"externalSource": "hubspot"
}'The family was enrolled and the schedule of cards begins.
{
"outcome": "created",
"intakeRequestId": "7f1d2c3b-4a5e-4f60-9b71-8c2d3e4f5a6b",
"caseId": "9c2f1e58-0a4b-4d0e-9a3f-7b2c1d5e8f40",
"created": true,
"warnings": [],
"missing": []
}An earlier request carried the same externalId, so the original recipient comes back untouched.
{
"outcome": "duplicate",
"intakeRequestId": "0b7e6a52-9d3c-4e1f-8a2b-5c4d3e2f1a0b",
"caseId": "9c2f1e58-0a4b-4d0e-9a3f-7b2c1d5e8f40",
"created": false,
"warnings": [],
"missing": []
}Everything was in order except the mailing address. The family is kept in the portal under Waiting on an address, where the director adds it and the cards are scheduled from there. A repeat with the same externalId refreshes the same hold.
{
"outcome": "held",
"intakeRequestId": "7f1d2c3b-4a5e-4f60-9b71-8c2d3e4f5a6b",
"caseId": null,
"created": false,
"warnings": [],
"missing": [
{ "field": "addressLine1", "message": "Street address is required." },
{ "field": "city", "message": "City is required." },
{ "field": "state", "message": "State is required." },
{ "field": "postalCode", "message": "Postal code is required." }
]
}Sent as application/problem+json, with one entry per field that could not be read. Every request, accepted or not, is listed under Recent activity in the portal with these same reasons.
{
"type": "https://lastingaftercare.com/errors/validation-failed",
"title": "Validation failed",
"status": 400,
"code": "validation_failed",
"errors": [
{ "field": "postalCode", "message": "Expected a 5-digit ZIP or ZIP+4." },
{ "field": "dateOfPassing", "message": "Could not read this as a date." }
]
}If you would like a hand wiring this into the CRM your team already uses, we are glad to walk through it with you on a short call, and the cards begin reaching family mailboxes from the first family you enroll.
Schedule a ConversationOr write to [email protected]