Search Documentation

Search for a documentation page...

Contact Messages API

REST API endpoints for contact form submissions and customer inbox management.

Contact messages cover two surfaces: a contact form endpoint for visitors to submit messages, and a customer inbox for store owners to browse, read, and reply to those messages.

The inbox merges two sources: email messages (sent and received via Resend) and contact-form submissions (from the storefront contact form). Every message in the list and detail responses includes a source field — "email" or "contact" — so you can distinguish them. Contact-form messages are always direction: "inbound" and have to, cc, bcc, replyTo, subject, html, and reason set to null.

Create Contact Message

POST /api/v1/contact-messages

Saves a contact form message and notifies the merchant by email. The email notification is sent in the background, so the response returns as soon as the message is stored.

Request Body

FieldTypeRequiredDescription
emailstringYesSender email address
messagestringYesMessage content (1-5000 characters)
routingKeystringNoOpaque label assigned by the storefront form (max 100 chars). The merchant maps labels to recipient mailboxes via settings.contactRoutingEmails; unmatched or missing keys fall back to notificationEmail.
curl -X POST \
-H "Authorization: Bearer your_api_key" \
-H "Content-Type: application/json" \
-d '{"email": "jane@example.com", "message": "Do you ship internationally?", "routingKey": "sales"}' \
https://your-store.yns.store/api/v1/contact-messages

Response (201)

{
"id": "0191abc0-1234-7def-8000-000000000001",
"storeId": "0191abc0-0000-7000-8000-000000000abc",
"email": "jane@example.com",
"message": "Do you ship internationally?",
"readAt": null,
"createdAt": "2024-06-15T10:30:00.000Z",
"updatedAt": "2024-06-15T10:30:00.000Z"
}

A 400 is returned with { error, details } when the email is malformed or the message is empty or over 5000 characters.


List Messages

GET /api/v1/messages

Returns a paginated list of inbound and outbound messages in the store's inbox.

Query Parameters

ParameterTypeDefaultDescription
limitnumber20Messages per page (1-100)
offsetnumber0Messages to skip
querystringSearch by sender address or subject
filterstringallMessage status: all, unread, or read
directionstringFilter by inbound or outbound
curl -H "Authorization: Bearer your_api_key" \
"https://your-store.yns.store/api/v1/messages?filter=unread&limit=10"

Response (200)

{
"data": [
{
"id": "0191abc0-1234-7def-8000-000000000001",
"source": "email",
"direction": "inbound",
"from": "jane@example.com",
"to": "store@yns.store",
"cc": null,
"bcc": null,
"replyTo": null,
"subject": "Shipping question",
"text": "Do you ship internationally?",
"html": null,
"reason": null,
"readAt": null,
"createdAt": "2024-06-15T10:30:00.000Z",
"updatedAt": "2024-06-15T10:30:00.000Z"
},
{
"id": "0191abc0-5678-7def-8000-000000000002",
"source": "contact",
"direction": "inbound",
"from": "alex@example.com",
"to": null,
"cc": null,
"bcc": null,
"replyTo": null,
"subject": null,
"text": "I'd like to place a bulk order.",
"html": null,
"reason": null,
"readAt": null,
"createdAt": "2024-06-15T09:15:00.000Z",
"updatedAt": "2024-06-15T09:15:00.000Z"
}
],
"meta": {
"count": 2,
"offset": 0,
"limit": 20
}
}

When direction=outbound is set, contact-form messages are excluded automatically since they are always inbound.


Get Message

GET /api/v1/messages/:id

Returns a single message by UUID.

curl -H "Authorization: Bearer your_api_key" \
https://your-store.yns.store/api/v1/messages/0191abc0-1234-7def-8000-000000000001

Returns 404 if the message does not exist.


Mark as Read

POST /api/v1/messages/:id/read

Marks an inbox message as read (sets readAt to the current time). Returns the updated message.

curl -X POST \
-H "Authorization: Bearer your_api_key" \
https://your-store.yns.store/api/v1/messages/0191abc0-1234-7def-8000-000000000001/read

Reply to Message

POST /api/v1/messages/:id/reply

Sends a reply email to the customer and records the outbound message in the inbox. Works for both email and contact-form messages — for contact-form submissions the default subject is "Re: your message". Only inbound messages can be replied to.

Request Body

FieldTypeRequiredDescription
bodystringYesPlain-text reply (1-50000 chars). Blank lines become paragraphs.
subjectstringNoOverride subject line (defaults to Re: <original subject>)
curl -X POST \
-H "Authorization: Bearer your_api_key" \
-H "Content-Type: application/json" \
-d '{"body": "Yes, we ship to over 50 countries!"}' \
https://your-store.yns.store/api/v1/messages/0191abc0-1234-7def-8000-000000000001/reply

Response (201)

{
"ok": true,
"sent": {
"to": "jane@example.com",
"subject": "Re: Shipping question",
"emailId": "msg_abc123"
}
}
StatusDescription
409Cannot reply to outbound messages
502Email delivery failed

Delete Message

DELETE /api/v1/messages/:id

Permanently deletes a message from the inbox.

curl -X DELETE \
-H "Authorization: Bearer your_api_key" \
https://your-store.yns.store/api/v1/messages/0191abc0-1234-7def-8000-000000000001

Response (200)

{
"ok": true,
"deleted": 1
}