Runs examples for real against your account. Test keys only; kept in this tab, never stored on our side. Get a key
ZapSMTP / Docs / Received emails

Mark read, set metadata

PATCH/v1/threads/{id}

Mark a conversation read or unread and set its metadata.

Requires a full-access live key; test keys get 403 test_key_restricted.

Omitted fields are kept.

Path parameters

idstring (UUID)required
Thread id

Body parameters

readboolean
true sets read_at to now (unread again once a new email arrives); false clears it.
metadataobject
Your own key-value pairs (a ticket id, a CRM deal), replacing the previous ones. Limits: at most 20 keys matching [A-Za-z0-9_-]{1,40}, values up to 500 bytes (UTF-8) (422 invalid_parameter).

Errors

validation_errorHTTP 400
invalid JSON / unknown field
restricted_api_keyHTTP 403
test_key_restrictedHTTP 403
test-mode keys can send test email and read, not change the account: use a live key
not_foundHTTP 404
thread not found
invalid_parameterHTTP 422
metadata limits
PATCH/v1/threads/{id}
curl -X PATCH 'https://zapsmtp.xyz/v1/threads/3f1c9a52-6b0e-5d4f-8a71-2c9e0b4d6f13' \
  -H "Authorization: Bearer $ZAP_API_KEY" \
  -H 'Content-Type: application/json' \
  -d '{
  "read": true,
  "metadata": {
    "ticket": "T-1042"
  }
}'
Set ZAP_API_KEY in your environment.
Response 200 OK
{
  "object": "thread",
  "id": "3f1c9a52-6b0e-5d4f-8a71-2c9e0b4d6f13",
  "subject": "Where is my order?",
  "participants": [
    "jane@example.org",
    "support@acme.com"
  ],
  "message_count": 3,
  "inbound_count": 2,
  "outbound_count": 1,
  "has_attachments": false,
  "first_message_at": "2026-10-21T15:10:02.904Z",
  "last_message_at": "2026-10-21T16:02:13.540Z",
  "last_inbound_at": "2026-10-21T16:02:13.540Z",
  "last_message": {
    "id": "019a1f52-0c1d-7f2e-8a3b-4c5d6e7f8091",
    "direction": "inbound",
    "from": "jane@example.org",
    "subject": "Re: Where is my order?"
  },
  "awaiting_reply": true,
  "unread": false,
  "read_at": "2026-10-21T16:05:00.000Z",
  "metadata": {
    "ticket": "T-1042"
  }
}