{"openapi":"3.1.0","info":{"title":"Email approval service","version":"0.1.0","description":"Agents create and revise email drafts and submit them for review. A person approves or rejects each one, and approved revisions are sent through Resend exactly once.\n\n## Errors\n\nEvery error has the shape `{ statusCode, message, name, docs_url }`. Branch on `name`; `message` says what to do next, and `X-Request-Id` identifies the request.\n\n| Code | Status | Cause | Resolution |\n|------|--------|-------|------------|\n| `validation_error` | 400 | A field has the wrong type or format or is over its size limit, the body is not valid JSON, or the body was not sent as JSON | Read `message` for the specific problem and how to fix it, then send the request again |\n| `invalid_idempotency_key` | 400 | The `Idempotency-Key` header is empty or longer than 256 characters | Send a key of 1 to 256 characters, such as a UUID, or leave the header out |\n| `missing_api_key` | 401 | The request has no `Authorization: Bearer <key>` header | Send the agent key or the reviewer key as `Authorization: Bearer <key>` |\n| `invalid_api_key` | 401 | The key in `Authorization` is not one this service issued | Check the key for typos, then use the agent key or the reviewer key you were given |\n| `invalid_permission` | 403 | The key is valid but not allowed here: agent keys never approve or send, reviewer keys never change drafts | Do not retry with another key. Agents poll GET /drafts/{id} until status is rejected, sent or failed; only the agent key changes drafts |\n| `not_found` | 404 | No route matches the method and path, or no resource has the id in the path | Check the method and path against the API reference, and the id against the one the create response returned |\n| `missing_required_field` | 422 | The body is missing one or more required fields | Add the fields named in `message` and send the request again |\n| `missing_required_parameter` | 422 | The query string is missing one or more required parameters | Add the parameters named in `message` and send the request again |\n| `invalid_parameter` | 422 | A path or query parameter has the wrong format, such as a draft `id` that is not a UUID | Use the format `message` gives for the path or query parameter it names, then send the request again |\n| `invalid_from_address` | 422 | `from` is not an email address, or it is not on the domain this service sends from | Leave `from` out to send from the default address, or use an address on the domain `message` names |\n| `revision_stale` | 409 | The revision the request names is not the current revision of the draft, usually because another revision was saved first | Fetch the draft, apply your change to `current_revision`, and send it again with its id |\n| `content_hash_mismatch` | 409 | The `content_hash` sent with an approval is not the hash of the revision it names, so what the reviewer saw is not what would be sent | Reload the draft, review `current_revision` again, and approve it with its own `content_hash` |\n| `draft_locked` | 409 | The draft is approved, sending or sent, so it can no longer change | Poll GET /drafts/{id} until it is sent or failed, then follow `next_step`. Create a new draft only for a different email |\n| `invalid_state_transition` | 409 | The draft is not in a status this action accepts, such as submitting a draft that was approved | Fetch the draft, read `status` and `next_step`, and do what `next_step` says |\n| `resource_locked` | 409 | Other requests kept changing the draft while this one was being saved | Wait a moment, fetch the draft, and send the request again |\n| `invalid_idempotent_request` | 409 | The `Idempotency-Key` was used in the last 24 hours for a request with a different body | Use a new key for a new draft. To get the first response again, send the original body with the same key |\n| `concurrent_idempotent_requests` | 409 | Another request with the same `Idempotency-Key` is still in progress | Wait a second and send the same request again with the same key: once the first one finishes, the retry returns its response |\n| `missing_webhook_signature` | 401 | A request to POST /webhooks/resend has no `svix-id`, `svix-timestamp` or `svix-signature` header, so it is not a Resend webhook | Only Resend calls this route; agents never do. Resend signs every event, so check that nothing between Resend and the service drops the `svix-*` headers |\n| `invalid_webhook_signature` | 401 | The `svix-signature` of a webhook does not match its body and `RESEND_WEBHOOK_SECRET`, or its `svix-timestamp` is more than 5 minutes from now | Nothing was recorded. Set `RESEND_WEBHOOK_SECRET` to the signing secret of this webhook in the Resend dashboard and redeploy; Resend retries the event |\n| `webhook_not_configured` | 503 | `RESEND_WEBHOOK_SECRET` is not set, so the service cannot verify Resend webhooks and records no delivery events | The operator sets `RESEND_WEBHOOK_SECRET` to the signing secret of the webhook in the Resend dashboard and redeploys; Resend retries the events it could not deliver |\n| `internal_server_error` | 500 | Something failed inside the service | Retry a GET, or POST /drafts with the same `Idempotency-Key` and body. Otherwise fetch the resource to check whether the change was saved before you retry. If it keeps failing, report the `X-Request-Id` |"},"servers":[{"url":"https://resend-devtools.riquetti.com.br/api"}],"components":{"responses":{"Error":{"description":"An error. Branch on `name`; `message` says what to do next.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"securitySchemes":{"agentKey":{"type":"http","scheme":"bearer","description":"The agent key, which starts with `agent_`. It creates, revises, submits and reads drafts, and can never approve, reject or send."},"reviewerKey":{"type":"http","scheme":"bearer","description":"The reviewer key, which starts with `reviewer_`. It reads drafts, lists the review queue, and approves or rejects a revision, from the review UI."}},"schemas":{"Error":{"type":"object","properties":{"statusCode":{"type":"integer","description":"The HTTP status code of the response."},"message":{"type":"string","description":"What went wrong and what to do next, written for a person or an agent."},"name":{"type":"string","enum":["validation_error","invalid_idempotency_key","missing_api_key","invalid_api_key","invalid_permission","not_found","missing_required_field","missing_required_parameter","invalid_parameter","invalid_from_address","revision_stale","content_hash_mismatch","draft_locked","invalid_state_transition","resource_locked","invalid_idempotent_request","concurrent_idempotent_requests","missing_webhook_signature","invalid_webhook_signature","webhook_not_configured","internal_server_error"],"description":"A stable error name. Branch on this, not on message."},"docs_url":{"type":"string","format":"uri","description":"A link to this error in the error reference."}},"required":["statusCode","message","name","docs_url"]},"ResendEmailEvent":{"type":"object","properties":{"type":{"type":"string","pattern":"^email\\.(sent|delivered|delivery_delayed|bounced|complained)$","description":"The Resend event type: email.sent, email.delivered, email.delivery_delayed, email.bounced or email.complained. Any other type is answered with 200 and ignored."},"created_at":{"type":"string","format":"date-time","description":"When the event happened, as an ISO 8601 timestamp. An event older than the one already recorded on the send does not replace it."},"data":{"type":"object","properties":{"email_id":{"type":"string","minLength":1,"description":"The id Resend gave the email, matched against `send.resend_email_id`."}},"required":["email_id"],"description":"The email the event is about."}},"required":["type","created_at","data"]},"Health":{"type":"object","properties":{"status":{"type":"string","enum":["ok"],"description":"Always \"ok\" while the service can answer requests."}},"required":["status"]},"Discovery":{"type":"object","properties":{"object":{"type":"string","enum":["discovery"],"description":"Always \"discovery\"."},"name":{"type":"string","description":"The name of this service."},"description":{"type":"string","description":"What this service does, in one paragraph."},"auth":{"type":"object","properties":{"header":{"type":"string","enum":["Authorization"],"description":"The header that carries the key."},"format":{"type":"string","enum":["Bearer <key>"],"description":"The value of that header, with <key> replaced by the key."},"description":{"type":"string","description":"How keys work, and where an agent gets one."},"keys":{"type":"array","items":{"type":"object","properties":{"scope":{"type":"string","enum":["agent","reviewer"],"description":"A key scope: agent for the key an agent uses, reviewer for the key a person uses in the review UI."},"prefix":{"type":"string","description":"Every key of this scope starts with this text."},"description":{"type":"string","description":"What a key of this scope can and cannot do."}},"required":["scope","prefix","description"]},"description":"One entry per kind of key."}},"required":["header","format","description","keys"],"description":"How to authenticate."},"endpoints":{"type":"array","items":{"type":"object","properties":{"method":{"type":"string","enum":["GET","POST","PUT","PATCH","DELETE"],"description":"The HTTP method."},"url":{"type":"string","description":"The absolute URL. Replace each {name} with a value, such as a draft id."},"summary":{"type":"string","description":"What the endpoint does."},"scopes":{"type":"array","items":{"type":"string","enum":["agent","reviewer"],"description":"A key scope: agent for the key an agent uses, reviewer for the key a person uses in the review UI."},"description":"The scopes whose key this endpoint accepts. An empty list means it needs no key."}},"required":["method","url","summary","scopes"]},"description":"Every endpoint an agent or a reviewer calls, read from the OpenAPI document."},"webhooks":{"type":"array","items":{"type":"object","properties":{"method":{"type":"string","enum":["GET","POST","PUT","PATCH","DELETE"],"description":"The HTTP method."},"url":{"type":"string","description":"The absolute URL to register in the Resend dashboard."},"summary":{"type":"string","description":"What the webhook receives."}},"required":["method","url","summary"]},"description":"Endpoints that Resend calls to report what happened to a sent email. They take no key: each request is verified by its Resend signature. Agents never call them; read `send.last_event` on the draft instead."},"links":{"type":"object","properties":{"openapi":{"type":"string","format":"uri","description":"The OpenAPI 3.1 document, with every route, field and error."},"docs":{"type":"string","format":"uri","description":"The API reference for people."},"errors":{"type":"string","format":"uri","description":"Every error name with its cause and how to fix it."},"llms":{"type":"string","format":"uri","description":"The workflow, endpoints and errors as llms.txt, for an agent to read before its first call."},"skill":{"type":"string","format":"uri","description":"The installable agent skill (SKILL.md). Its references are under the same path, in references/."}},"required":["openapi","docs","errors","llms","skill"],"description":"Where to read more."},"sender":{"type":"object","properties":{"default_from":{"type":"string","description":"The address every email is sent from when a draft leaves `from` out."},"allowed_domain":{"type":"string","description":"The only domain `from` may use, because it is the domain verified in Resend. A display name in `from` must not contain @."}},"required":["default_from","allowed_domain"],"description":"Who emails are sent from. Leave `from` out of a draft to use default_from."},"next_step":{"type":"string","description":"The first call a new agent should make."}},"required":["object","name","description","auth","endpoints","webhooks","links","sender","next_step"]},"Draft":{"type":"object","properties":{"object":{"type":"string","enum":["draft"],"description":"Always \"draft\"."},"id":{"type":"string","format":"uuid","description":"The draft id."},"status":{"type":"string","enum":["draft","pending_review","approved","rejected","sending","sent","failed"],"description":"Where the draft is in review: draft, pending_review, approved, rejected, sending, sent or failed."},"latest_review":{"$ref":"#/components/schemas/Review"},"send":{"$ref":"#/components/schemas/Send"},"unconfirmed_send":{"$ref":"#/components/schemas/UnconfirmedSend"},"next_step":{"type":"string","description":"What the caller should do next with this draft, written for the role of the key that asked (agent or reviewer), with the exact request to send."},"created_at":{"type":"string","description":"ISO 8601 timestamp, in UTC."},"updated_at":{"type":"string","description":"ISO 8601 timestamp, in UTC."},"current_revision":{"$ref":"#/components/schemas/Revision"}},"required":["object","id","status","latest_review","send","unconfirmed_send","next_step","created_at","updated_at","current_revision"]},"Review":{"type":["object","null"],"properties":{"object":{"type":"string","enum":["review"],"description":"Always \"review\"."},"id":{"type":"string","format":"uuid","description":"The review id."},"revision_id":{"type":"string","format":"uuid","description":"The revision the person decided on. It can be older than `current_revision` once the draft is revised again."},"decision":{"type":"string","enum":["approved","rejected"],"description":"approved or rejected."},"reason":{"type":["string","null"],"description":"Why the revision was rejected, written by the reviewer for the agent to act on; null for an approval."},"created_at":{"type":"string","description":"ISO 8601 timestamp, in UTC."}},"required":["object","id","revision_id","decision","reason","created_at"],"description":"The most recent decision on any revision of this draft, or null if no one has decided yet. After a rejection, `reason` says what to change."},"Send":{"type":["object","null"],"properties":{"object":{"type":"string","enum":["send"],"description":"Always \"send\"."},"id":{"type":"string","format":"uuid","description":"The send id."},"status":{"type":"string","enum":["queued","sending","sent","failed"],"description":"queued (waiting for its next attempt), sending (an attempt was claimed and may be in flight), sent, or failed."},"failure_reason":{"type":["string","null"],"enum":["rejected","outcome_unknown",null],"description":"Why a failed send ended, or null. `rejected`: Resend refused the email, so it was not sent. `outcome_unknown`: an attempt whose outcome is unknown (a timeout, a 5xx) may have delivered it, and the send could not be retried safely, either because 23 hours passed or because a later attempt was refused."},"last_error":{"type":["string","null"],"description":"The last send error, as `reason (name [status]): message`, or null. Set while a send waits to be retried, too. Most come from Resend; `outcome_unknown` is written by this service."},"resend_email_id":{"type":["string","null"],"description":"The id Resend gave the email once it was sent, or null."},"attempts":{"type":"integer","description":"How many send attempts were claimed. Every attempt carries the same Idempotency-Key, so Resend delivers the email at most once."},"sent_at":{"type":["string","null"],"description":"When Resend accepted the email, or null."},"last_event":{"type":["string","null"],"enum":["sent","delivered","delivery_delayed","bounced","complained",null],"description":"What Resend last reported about the email after it was sent, from its webhooks, as on Resend's own email object; null until the first event arrives, and always null when the operator has not set up the webhook. `sent`: Resend accepted it and is delivering it to the recipient's mail server. `delivered`: the server accepted it. `delivery_delayed`: the server has not accepted it yet and Resend keeps trying. `bounced`: the server refused it, so it was not delivered. `complained`: a recipient marked it as spam. An older event never replaces a newer one, and `bounced` or `complained` is never replaced by `sent`, `delivered` or `delivery_delayed`."},"last_event_at":{"type":["string","null"],"description":"When the event in `last_event` happened, according to Resend, or null."}},"required":["object","id","status","failure_reason","last_error","resend_email_id","attempts","sent_at","last_event","last_event_at"],"description":"The send of `current_revision` once it is approved, or null before that. Check it when `status` is failed: `failure_reason` says whether the email may already have been delivered."},"UnconfirmedSend":{"allOf":[{"$ref":"#/components/schemas/Send"},{"type":["object","null"],"properties":{"revision_id":{"type":"string","format":"uuid","description":"The earlier revision this send was for. It is never `current_revision`."},"revision_number":{"type":"integer","description":"The number of that earlier revision."}},"required":["revision_id","revision_number"]}],"description":"The latest send of an earlier revision of this draft that ended `failed` with `failure_reason` `outcome_unknown`, or null. When it is set, that earlier email may already have been delivered, and approving `current_revision` sends a new email under a new Idempotency-Key, so Resend cannot drop it as a repeat. A person checks the Resend dashboard for the earlier email before approving."},"Revision":{"type":"object","properties":{"object":{"type":"string","enum":["revision"],"description":"Always \"revision\"."},"id":{"type":"string","format":"uuid","description":"The revision id. Send it as `base_revision_id` to revise and as `revision_id` to submit."},"number":{"type":"integer","description":"1 for the first revision, then one more for each revise."},"base_revision_id":{"type":["string","null"],"format":"uuid","description":"The revision this one was written on top of; null for the first revision."},"content_hash":{"type":"string","description":"SHA-256 of the canonical content. An approval applies to this exact hash."},"from":{"type":"string","description":"Sender address."},"to":{"type":"array","items":{"type":"string"},"description":"Recipient addresses."},"cc":{"type":"array","items":{"type":"string"},"description":"Cc addresses."},"bcc":{"type":"array","items":{"type":"string"},"description":"Bcc addresses."},"reply_to":{"type":"array","items":{"type":"string"},"description":"Reply-to addresses."},"subject":{"type":"string","description":"Email subject."},"created_at":{"type":"string","description":"ISO 8601 timestamp, in UTC."},"html":{"type":["string","null"],"description":"HTML body, or null."},"text":{"type":["string","null"],"description":"Plain-text body, or null."}},"required":["object","id","number","base_revision_id","content_hash","from","to","cc","bcc","reply_to","subject","created_at","html","text"],"description":"The latest revision. Reviews and sends apply to it."},"DraftList":{"type":"object","properties":{"object":{"type":"string","enum":["list"],"description":"Always \"list\"."},"data":{"type":"array","items":{"$ref":"#/components/schemas/DraftSummary"},"description":"The drafts on this page, as summaries without the email bodies. The review queue (`status=pending_review`) comes in the order the drafts were last submitted, longest waiting first; every other list comes newest first."},"has_more":{"type":"boolean","description":"Whether more drafts follow in the direction you are paging. To get them, send the id of the last draft as `after` (or the first as `before`)."}},"required":["object","data","has_more"]},"DraftSummary":{"type":"object","properties":{"object":{"type":"string","enum":["draft"],"description":"Always \"draft\"."},"id":{"type":"string","format":"uuid","description":"The draft id."},"status":{"type":"string","enum":["draft","pending_review","approved","rejected","sending","sent","failed"],"description":"Where the draft is in review: draft, pending_review, approved, rejected, sending, sent or failed."},"latest_review":{"$ref":"#/components/schemas/Review"},"send":{"$ref":"#/components/schemas/Send"},"unconfirmed_send":{"$ref":"#/components/schemas/UnconfirmedSend"},"next_step":{"type":"string","description":"What the caller should do next with this draft, written for the role of the key that asked (agent or reviewer), with the exact request to send."},"created_at":{"type":"string","description":"ISO 8601 timestamp, in UTC."},"updated_at":{"type":"string","description":"ISO 8601 timestamp, in UTC."},"current_revision":{"$ref":"#/components/schemas/RevisionSummary"}},"required":["object","id","status","latest_review","send","unconfirmed_send","next_step","created_at","updated_at","current_revision"]},"RevisionSummary":{"type":"object","properties":{"object":{"type":"string","enum":["revision"],"description":"Always \"revision\"."},"id":{"type":"string","format":"uuid","description":"The revision id. Send it as `base_revision_id` to revise and as `revision_id` to submit."},"number":{"type":"integer","description":"1 for the first revision, then one more for each revise."},"base_revision_id":{"type":["string","null"],"format":"uuid","description":"The revision this one was written on top of; null for the first revision."},"content_hash":{"type":"string","description":"SHA-256 of the canonical content. An approval applies to this exact hash."},"from":{"type":"string","description":"Sender address."},"to":{"type":"array","items":{"type":"string"},"description":"Recipient addresses."},"cc":{"type":"array","items":{"type":"string"},"description":"Cc addresses."},"bcc":{"type":"array","items":{"type":"string"},"description":"Bcc addresses."},"reply_to":{"type":"array","items":{"type":"string"},"description":"Reply-to addresses."},"subject":{"type":"string","description":"Email subject."},"created_at":{"type":"string","description":"ISO 8601 timestamp, in UTC."}},"required":["object","id","number","base_revision_id","content_hash","from","to","cc","bcc","reply_to","subject","created_at"],"description":"The latest revision without its `html` and `text` bodies. Fetch the draft with GET /drafts/{id} to read them."},"DraftEventList":{"type":"object","properties":{"object":{"type":"string","enum":["list"],"description":"Always \"list\"."},"data":{"type":"array","items":{"$ref":"#/components/schemas/DraftEvent"},"description":"The history of the draft, oldest first, with the delivery events Resend reported merged in by time. A delivery event never comes before the `sent` of its revision."},"has_more":{"type":"boolean","enum":[false],"description":"Always false: a draft has a short history, so it all comes in one response, without paging."}},"required":["object","data","has_more"]},"DraftEvent":{"type":"object","properties":{"object":{"type":"string","enum":["draft_event"],"description":"Always \"draft_event\"."},"id":{"type":"string","description":"The event id: a UUID for an event this service recorded, or the Resend webhook message id for a delivery event."},"type":{"type":"string","enum":["created","revised","submitted","approved","rejected","send_queued","send_retry_scheduled","sent","send_failed","delivered","delivery_delayed","bounced","complained"],"description":"What happened. `created`, `revised` and `submitted` come from the agent; `approved` and `rejected` from a person; `send_queued` (the approved revision was queued to send), `send_retry_scheduled` (an attempt failed and will be retried with the same Idempotency-Key), `sent` (Resend accepted the email) and `send_failed` from this service; `delivered`, `delivery_delayed`, `bounced` and `complained` are what Resend reported after sending."},"actor":{"type":"string","enum":["agent","reviewer","system","resend"],"description":"Who caused it: agent (an agent key), reviewer (a person with a reviewer key), system (the send worker) or resend (a Resend webhook)."},"revision_id":{"type":"string","format":"uuid","description":"The revision the event is about. For a delivery event, the revision whose send Resend reported on."},"revision_number":{"type":"integer","description":"The number of that revision."},"reason":{"type":["string","null"],"description":"On `rejected`, why the person rejected the revision, written for the agent to act on; null on every other type. Read it before writing the next revision."},"failure_reason":{"type":["string","null"],"enum":["rejected","outcome_unknown",null],"description":"On `send_failed`, `rejected` (Resend refused the email, so nothing was delivered) or `outcome_unknown` (it may have been delivered); null on every other type."},"created_at":{"type":"string","description":"When it happened, in ISO 8601 and UTC. For a delivery event, the time Resend gave it."}},"required":["object","id","type","actor","revision_id","revision_number","reason","failure_reason","created_at"]},"RevisionList":{"type":"object","properties":{"object":{"type":"string","enum":["list"],"description":"Always \"list\"."},"data":{"type":"array","items":{"$ref":"#/components/schemas/RevisionSummary"},"description":"Every revision of the draft without its `html` and `text` bodies, oldest first: revision 1, then one per revise. The last one is `current_revision`. Read one with its bodies with GET /drafts/{id}/revisions/{revision_id}."},"has_more":{"type":"boolean","enum":[false],"description":"Always false: the list holds no bodies, so even a long history comes in one response, without paging."}},"required":["object","data","has_more"]},"WebhookReceipt":{"type":"object","properties":{"object":{"type":"string","enum":["webhook_event"],"description":"Always \"webhook_event\"."},"id":{"type":"string","description":"The `svix-id` of the event."},"outcome":{"type":"string","enum":["recorded","outdated","duplicate","unknown_email","ignored"],"description":"What the service did with the event. `recorded`: it is now the `last_event` of the send. `outdated`: a newer event was already recorded, so the send kept it. `duplicate`: this event id was processed before, so nothing changed. `unknown_email`: no send has this `email_id`, so nothing was written. `ignored`: the event type is not one this service records."}},"required":["object","id","outcome"]}},"parameters":{}},"paths":{"/health":{"get":{"summary":"Check that the service is up","description":"Returns 200 while the process can answer HTTP requests. Hosts and uptime monitors call it; it needs no credentials.","responses":{"200":{"description":"The service is up.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Health"}}}}}}},"/":{"get":{"summary":"Describe the service","description":"Lists every endpoint with the key it needs, explains how to send a key and links to the full docs. It needs no key. The site root returns the same document to a request that prefers JSON (Accept: application/json).","responses":{"200":{"description":"The discovery document.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Discovery"}}}}}}},"/drafts":{"post":{"summary":"Create a draft","description":"Creates a draft with its first revision, in `draft` status. Nothing is sent until a person approves it. Send an `Idempotency-Key` header, as with Resend's POST /emails, so a retry never creates a second draft: the same key and body within 24 hours return the first response. Next, submit the revision for review.","security":[{"agentKey":[]}],"parameters":[{"schema":{"type":"string","minLength":1,"maxLength":256,"description":"One key per draft, 1 to 256 characters, such as `create-draft/<uuid>`. The same key and body within 24 hours return the first response, with `Idempotent-Replayed: true`, and create nothing. A failed request is not stored.","example":"create-draft/4f8c2b1e"},"required":false,"description":"One key per draft, 1 to 256 characters, such as `create-draft/<uuid>`. The same key and body within 24 hours return the first response, with `Idempotent-Replayed: true`, and create nothing. A failed request is not stored.","name":"idempotency-key","in":"header"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"from":{"type":"string","maxLength":320,"description":"Sender address, in the `email@example.com` or `Name <email@example.com>` format, at most 320 characters. Leave it out to send from reviews@mail.riquetti.com.br. When set, it must be an address on mail.riquetti.com.br, and its display name must not contain @."},"to":{"anyOf":[{"type":"string","maxLength":320},{"type":"array","items":{"type":"string","maxLength":320},"minItems":1,"maxItems":50}],"description":"Recipient addresses. One address or an array of up to 50, each in the `email@example.com` or `Name <email@example.com>` format and at most 320 characters long."},"cc":{"anyOf":[{"type":"string","maxLength":320},{"type":"array","items":{"type":"string","maxLength":320},"minItems":0,"maxItems":50}],"description":"Cc addresses. An empty array is the same as leaving it out. One address or an array of up to 50, each in the `email@example.com` or `Name <email@example.com>` format and at most 320 characters long."},"bcc":{"anyOf":[{"type":"string","maxLength":320},{"type":"array","items":{"type":"string","maxLength":320},"minItems":0,"maxItems":50}],"description":"Bcc addresses. An empty array is the same as leaving it out. One address or an array of up to 50, each in the `email@example.com` or `Name <email@example.com>` format and at most 320 characters long."},"reply_to":{"anyOf":[{"type":"string","maxLength":320},{"type":"array","items":{"type":"string","maxLength":320},"minItems":0,"maxItems":50}],"description":"Reply-to addresses. An empty array is the same as leaving it out. One address or an array of up to 50, each in the `email@example.com` or `Name <email@example.com>` format and at most 320 characters long."},"subject":{"type":"string","maxLength":998,"pattern":"\\S","description":"Email subject: one line of at most 998 characters, without line breaks, control characters or bidirectional controls."},"html":{"type":["string","null"],"maxLength":1000000,"description":"HTML body, at most 1,000,000 characters. Send `html`, `text` or both; null is the same as leaving it out."},"text":{"type":["string","null"],"maxLength":1000000,"description":"Plain-text body, at most 1,000,000 characters. Send `html`, `text` or both; null is the same as leaving it out."}},"required":["to","subject"],"additionalProperties":false}}}},"responses":{"201":{"description":"The draft, with revision 1 as its current revision. A replay returns the first response again, with `Idempotent-Replayed: true`.","headers":{"Idempotent-Replayed":{"schema":{"type":"string","enum":["true"],"description":"Present when this is the stored response of an earlier request with the same `Idempotency-Key`; no draft was created."},"required":false,"description":"Present when this is the stored response of an earlier request with the same `Idempotency-Key`; no draft was created."}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Draft"}}}},"400":{"$ref":"#/components/responses/Error","description":"`validation_error`: A field has the wrong type or format or is over its size limit, the body is not valid JSON, or the body was not sent as JSON. `invalid_idempotency_key`: The `Idempotency-Key` header is empty or longer than 256 characters"},"401":{"$ref":"#/components/responses/Error","description":"`missing_api_key`: The request has no `Authorization: Bearer <key>` header. `invalid_api_key`: The key in `Authorization` is not one this service issued"},"403":{"$ref":"#/components/responses/Error","description":"`invalid_permission`: The key is valid but not allowed here: agent keys never approve or send, reviewer keys never change drafts"},"409":{"$ref":"#/components/responses/Error","description":"`invalid_idempotent_request`: The `Idempotency-Key` was used in the last 24 hours for a request with a different body. `concurrent_idempotent_requests`: Another request with the same `Idempotency-Key` is still in progress"},"422":{"$ref":"#/components/responses/Error","description":"`missing_required_field`: The body is missing one or more required fields. `invalid_from_address`: `from` is not an email address, or it is not on the domain this service sends from"},"500":{"$ref":"#/components/responses/Error","description":"`internal_server_error`: Something failed inside the service"}}},"get":{"summary":"List drafts","description":"Lists drafts as summaries (the current revision without its `html` and `text` bodies, plus the latest review), a page at a time, in Resend's list shape. Filter by `status`; `status=pending_review` is the review queue, in the order drafts were last submitted, longest waiting first. Every other list comes newest first. Page with `limit` and with `after` or `before`, as Resend's list endpoints do. Fetch a draft with GET /drafts/{id} to read its bodies.","security":[{"agentKey":[]},{"reviewerKey":[]}],"parameters":[{"schema":{"type":"string","enum":["draft","pending_review","approved","rejected","sending","sent","failed"],"description":"Only list drafts in this status. The review queue is `pending_review`, longest waiting first."},"required":false,"description":"Only list drafts in this status. The review queue is `pending_review`, longest waiting first.","name":"status","in":"query"},{"schema":{"type":"integer","minimum":1,"maximum":100,"default":20,"description":"How many drafts to return, from 1 to 100. Defaults to 20."},"required":false,"description":"How many drafts to return, from 1 to 100. Defaults to 20.","name":"limit","in":"query"},{"schema":{"type":"string","format":"uuid","description":"Return the drafts that come after this draft id in the list. Pass the id of the last draft of the previous page. Cannot be sent with `before`."},"required":false,"description":"Return the drafts that come after this draft id in the list. Pass the id of the last draft of the previous page. Cannot be sent with `before`.","name":"after","in":"query"},{"schema":{"type":"string","format":"uuid","description":"Return the drafts that come before this draft id in the list. Pass the id of the first draft of the current page. Cannot be sent with `after`."},"required":false,"description":"Return the drafts that come before this draft id in the list. Pass the id of the first draft of the current page. Cannot be sent with `after`.","name":"before","in":"query"}],"responses":{"200":{"description":"A page of drafts.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DraftList"}}}},"401":{"$ref":"#/components/responses/Error","description":"`missing_api_key`: The request has no `Authorization: Bearer <key>` header. `invalid_api_key`: The key in `Authorization` is not one this service issued"},"422":{"$ref":"#/components/responses/Error","description":"`invalid_parameter`: A path or query parameter has the wrong format, such as a draft `id` that is not a UUID"},"500":{"$ref":"#/components/responses/Error","description":"`internal_server_error`: Something failed inside the service"}}}},"/drafts/{id}":{"get":{"summary":"Get a draft","description":"Returns the draft, its status and its current revision. Poll it after submitting until the status is rejected, sent or failed.","security":[{"agentKey":[]},{"reviewerKey":[]}],"parameters":[{"schema":{"type":"string","format":"uuid","description":"The draft id returned by POST /drafts."},"required":true,"description":"The draft id returned by POST /drafts.","name":"id","in":"path"}],"responses":{"200":{"description":"The draft.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Draft"}}}},"401":{"$ref":"#/components/responses/Error","description":"`missing_api_key`: The request has no `Authorization: Bearer <key>` header. `invalid_api_key`: The key in `Authorization` is not one this service issued"},"404":{"$ref":"#/components/responses/Error","description":"`not_found`: No draft has this id. Check the id from the create response."},"422":{"$ref":"#/components/responses/Error","description":"`invalid_parameter`: A path or query parameter has the wrong format, such as a draft `id` that is not a UUID"},"500":{"$ref":"#/components/responses/Error","description":"`internal_server_error`: Something failed inside the service"}}}},"/drafts/{id}/events":{"get":{"summary":"List a draft's events","description":"Returns the history of the draft, oldest first: who created, revised, submitted, approved or rejected each revision, how its send went, and what Resend reported after sending. Use it to read why earlier revisions were rejected before writing the next one, or to show a timeline. A draft has a short history, so it all comes in one response, without paging.","security":[{"agentKey":[]},{"reviewerKey":[]}],"parameters":[{"schema":{"type":"string","format":"uuid","description":"The draft id returned by POST /drafts."},"required":true,"description":"The draft id returned by POST /drafts.","name":"id","in":"path"}],"responses":{"200":{"description":"The events of the draft.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DraftEventList"}}}},"401":{"$ref":"#/components/responses/Error","description":"`missing_api_key`: The request has no `Authorization: Bearer <key>` header. `invalid_api_key`: The key in `Authorization` is not one this service issued"},"404":{"$ref":"#/components/responses/Error","description":"`not_found`: No draft has this id. Check the id from the create response."},"422":{"$ref":"#/components/responses/Error","description":"`invalid_parameter`: A path or query parameter has the wrong format, such as a draft `id` that is not a UUID"},"500":{"$ref":"#/components/responses/Error","description":"`internal_server_error`: Something failed inside the service"}}}},"/drafts/{id}/revisions":{"get":{"summary":"List a draft's revisions","description":"Returns every revision of the draft without its bodies, oldest first: recipients, subject and content hash, so you can see which revisions exist and what changed in the envelope. The last one is `current_revision`. Read a revision with its bodies with GET /drafts/{id}/revisions/{revision_id}. The list comes in one response, without paging.","security":[{"agentKey":[]},{"reviewerKey":[]}],"parameters":[{"schema":{"type":"string","format":"uuid","description":"The draft id returned by POST /drafts."},"required":true,"description":"The draft id returned by POST /drafts.","name":"id","in":"path"}],"responses":{"200":{"description":"The revisions of the draft.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RevisionList"}}}},"401":{"$ref":"#/components/responses/Error","description":"`missing_api_key`: The request has no `Authorization: Bearer <key>` header. `invalid_api_key`: The key in `Authorization` is not one this service issued"},"404":{"$ref":"#/components/responses/Error","description":"`not_found`: No draft has this id. Check the id from the create response."},"422":{"$ref":"#/components/responses/Error","description":"`invalid_parameter`: A path or query parameter has the wrong format, such as a draft `id` that is not a UUID"},"500":{"$ref":"#/components/responses/Error","description":"`internal_server_error`: Something failed inside the service"}}},"post":{"summary":"Revise a draft","description":"Writes a new revision with the whole email and makes it current. Name the revision you edited in `base_revision_id`; if another revision was saved first, nothing is written and the response is 409 `revision_stale`. Revising a draft that is pending review withdraws it from review, and revising a rejected or failed draft returns it to `draft`. Next, submit the new revision.","security":[{"agentKey":[]}],"parameters":[{"schema":{"type":"string","format":"uuid","description":"The draft id returned by POST /drafts."},"required":true,"description":"The draft id returned by POST /drafts.","name":"id","in":"path"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"base_revision_id":{"type":"string","format":"uuid","description":"The id of the revision you edited: `current_revision.id` from the draft you last fetched. If another revision was written since, the request fails with `revision_stale` instead of overwriting it."},"from":{"type":"string","maxLength":320,"description":"Sender address, in the `email@example.com` or `Name <email@example.com>` format, at most 320 characters. Leave it out to send from reviews@mail.riquetti.com.br. When set, it must be an address on mail.riquetti.com.br, and its display name must not contain @."},"to":{"anyOf":[{"type":"string","maxLength":320},{"type":"array","items":{"type":"string","maxLength":320},"minItems":1,"maxItems":50}],"description":"Recipient addresses. One address or an array of up to 50, each in the `email@example.com` or `Name <email@example.com>` format and at most 320 characters long."},"cc":{"anyOf":[{"type":"string","maxLength":320},{"type":"array","items":{"type":"string","maxLength":320},"minItems":0,"maxItems":50}],"description":"Cc addresses. An empty array is the same as leaving it out. One address or an array of up to 50, each in the `email@example.com` or `Name <email@example.com>` format and at most 320 characters long."},"bcc":{"anyOf":[{"type":"string","maxLength":320},{"type":"array","items":{"type":"string","maxLength":320},"minItems":0,"maxItems":50}],"description":"Bcc addresses. An empty array is the same as leaving it out. One address or an array of up to 50, each in the `email@example.com` or `Name <email@example.com>` format and at most 320 characters long."},"reply_to":{"anyOf":[{"type":"string","maxLength":320},{"type":"array","items":{"type":"string","maxLength":320},"minItems":0,"maxItems":50}],"description":"Reply-to addresses. An empty array is the same as leaving it out. One address or an array of up to 50, each in the `email@example.com` or `Name <email@example.com>` format and at most 320 characters long."},"subject":{"type":"string","maxLength":998,"pattern":"\\S","description":"Email subject: one line of at most 998 characters, without line breaks, control characters or bidirectional controls."},"html":{"type":["string","null"],"maxLength":1000000,"description":"HTML body, at most 1,000,000 characters. Send `html`, `text` or both; null is the same as leaving it out."},"text":{"type":["string","null"],"maxLength":1000000,"description":"Plain-text body, at most 1,000,000 characters. Send `html`, `text` or both; null is the same as leaving it out."}},"required":["base_revision_id","to","subject"],"additionalProperties":false,"description":"The whole email for the new revision. Fields you leave out are not copied from the base revision."}}}},"responses":{"201":{"description":"The draft, with the new revision as its current revision.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Draft"}}}},"400":{"$ref":"#/components/responses/Error","description":"`validation_error`: A field has the wrong type or format or is over its size limit, the body is not valid JSON, or the body was not sent as JSON"},"401":{"$ref":"#/components/responses/Error","description":"`missing_api_key`: The request has no `Authorization: Bearer <key>` header. `invalid_api_key`: The key in `Authorization` is not one this service issued"},"403":{"$ref":"#/components/responses/Error","description":"`invalid_permission`: The key is valid but not allowed here: agent keys never approve or send, reviewer keys never change drafts"},"404":{"$ref":"#/components/responses/Error","description":"`not_found`: No draft has this id. Check the id from the create response."},"409":{"$ref":"#/components/responses/Error","description":"`revision_stale`: The revision the request names is not the current revision of the draft, usually because another revision was saved first. `draft_locked`: The draft is approved, sending or sent, so it can no longer change. `resource_locked`: Other requests kept changing the draft while this one was being saved"},"422":{"$ref":"#/components/responses/Error","description":"`invalid_parameter`: A path or query parameter has the wrong format, such as a draft `id` that is not a UUID. `missing_required_field`: The body is missing one or more required fields. `invalid_from_address`: `from` is not an email address, or it is not on the domain this service sends from"},"500":{"$ref":"#/components/responses/Error","description":"`internal_server_error`: Something failed inside the service"}}}},"/drafts/{id}/revisions/{revision_id}":{"get":{"summary":"Get a revision","description":"Returns one revision of the draft with its `html` and `text` bodies, current or not. Use it to read what an earlier, rejected revision said, or to compare two revisions.","security":[{"agentKey":[]},{"reviewerKey":[]}],"parameters":[{"schema":{"type":"string","format":"uuid","description":"The draft id returned by POST /drafts."},"required":true,"description":"The draft id returned by POST /drafts.","name":"id","in":"path"},{"schema":{"type":"string","format":"uuid","description":"The revision id, from GET /drafts/{id}/revisions or the `revision_id` of an event."},"required":true,"description":"The revision id, from GET /drafts/{id}/revisions or the `revision_id` of an event.","name":"revision_id","in":"path"}],"responses":{"200":{"description":"The revision.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Revision"}}}},"401":{"$ref":"#/components/responses/Error","description":"`missing_api_key`: The request has no `Authorization: Bearer <key>` header. `invalid_api_key`: The key in `Authorization` is not one this service issued"},"404":{"$ref":"#/components/responses/Error","description":"`not_found`: No draft has this id, or the draft has no revision with this id."},"422":{"$ref":"#/components/responses/Error","description":"`invalid_parameter`: A path or query parameter has the wrong format, such as a draft `id` that is not a UUID"},"500":{"$ref":"#/components/responses/Error","description":"`internal_server_error`: Something failed inside the service"}}}},"/drafts/{id}/submit":{"post":{"summary":"Submit a draft for review","description":"Puts the current revision in front of a person, in `pending_review`. Name it in `revision_id`; if a newer revision exists, the response is 409 `revision_stale`. Submitting a revision that is already pending review returns 200 with the draft. Next, poll GET /drafts/{id} until status is rejected, sent or failed.","security":[{"agentKey":[]}],"parameters":[{"schema":{"type":"string","format":"uuid","description":"The draft id returned by POST /drafts."},"required":true,"description":"The draft id returned by POST /drafts.","name":"id","in":"path"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"revision_id":{"type":"string","format":"uuid","description":"The id of the revision to submit: `current_revision.id` from the draft you last fetched, so the reviewer sees exactly the content you checked."}},"required":["revision_id"],"additionalProperties":false}}}},"responses":{"200":{"description":"The draft, now pending review.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Draft"}}}},"400":{"$ref":"#/components/responses/Error","description":"`validation_error`: A field has the wrong type or format or is over its size limit, the body is not valid JSON, or the body was not sent as JSON"},"401":{"$ref":"#/components/responses/Error","description":"`missing_api_key`: The request has no `Authorization: Bearer <key>` header. `invalid_api_key`: The key in `Authorization` is not one this service issued"},"403":{"$ref":"#/components/responses/Error","description":"`invalid_permission`: The key is valid but not allowed here: agent keys never approve or send, reviewer keys never change drafts"},"404":{"$ref":"#/components/responses/Error","description":"`not_found`: No draft has this id. Check the id from the create response."},"409":{"$ref":"#/components/responses/Error","description":"`revision_stale`: The revision the request names is not the current revision of the draft, usually because another revision was saved first. `invalid_state_transition`: The draft is not in a status this action accepts, such as submitting a draft that was approved. `resource_locked`: Other requests kept changing the draft while this one was being saved"},"422":{"$ref":"#/components/responses/Error","description":"`invalid_parameter`: A path or query parameter has the wrong format, such as a draft `id` that is not a UUID. `missing_required_field`: The body is missing one or more required fields"},"500":{"$ref":"#/components/responses/Error","description":"`internal_server_error`: Something failed inside the service"}}}},"/drafts/{id}/approve":{"post":{"summary":"Approve a revision and send it","description":"A person approves the exact revision they read, named by `revision_id` and `content_hash`. In one step the draft becomes `approved` and the send is queued; that revision is sent through Resend once and can no longer be revised. If its send fails, the agent can write and submit a new revision, which needs a new approval. If the agent saved a newer revision, nothing is approved and the response is 409 `revision_stale`. Approving the same revision again returns 200 with the draft. Only the reviewer key can call it.","security":[{"reviewerKey":[]}],"parameters":[{"schema":{"type":"string","format":"uuid","description":"The draft id returned by POST /drafts."},"required":true,"description":"The draft id returned by POST /drafts.","name":"id","in":"path"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"revision_id":{"type":"string","format":"uuid","description":"The id of the revision you reviewed: `current_revision.id` from the draft you read. If the agent saved a newer revision since, the request fails with `revision_stale` and nothing is decided."},"content_hash":{"type":"string","pattern":"^[0-9a-f]{64}$","description":"`current_revision.content_hash` from the draft you read. The approval binds to this exact content, and the email sent is the revision with this hash."}},"required":["revision_id","content_hash"],"additionalProperties":false}}}},"responses":{"200":{"description":"The draft, with the approval as `latest_review`. A repeat of an approval already made returns the draft in its current status, such as `sending`, `sent` or `failed`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Draft"}}}},"400":{"$ref":"#/components/responses/Error","description":"`validation_error`: A field has the wrong type or format or is over its size limit, the body is not valid JSON, or the body was not sent as JSON"},"401":{"$ref":"#/components/responses/Error","description":"`missing_api_key`: The request has no `Authorization: Bearer <key>` header. `invalid_api_key`: The key in `Authorization` is not one this service issued"},"403":{"$ref":"#/components/responses/Error","description":"`invalid_permission`: The key is valid but not allowed here: agent keys never approve or send, reviewer keys never change drafts"},"404":{"$ref":"#/components/responses/Error","description":"`not_found`: No draft has this id. Check the id from the create response."},"409":{"$ref":"#/components/responses/Error","description":"`revision_stale`: The revision the request names is not the current revision of the draft, usually because another revision was saved first. `content_hash_mismatch`: The `content_hash` sent with an approval is not the hash of the revision it names, so what the reviewer saw is not what would be sent. `invalid_state_transition`: The draft is not in a status this action accepts, such as submitting a draft that was approved. `resource_locked`: Other requests kept changing the draft while this one was being saved"},"422":{"$ref":"#/components/responses/Error","description":"`invalid_parameter`: A path or query parameter has the wrong format, such as a draft `id` that is not a UUID. `missing_required_field`: The body is missing one or more required fields"},"500":{"$ref":"#/components/responses/Error","description":"`internal_server_error`: Something failed inside the service"}}}},"/drafts/{id}/reject":{"post":{"summary":"Reject a revision","description":"A person rejects the revision they read, named by `revision_id`, and says why in `reason`. The draft becomes `rejected`; the agent reads the reason in `latest_review` and writes a new revision. If the agent saved a newer revision, nothing is rejected and the response is 409 `revision_stale`. Rejecting the same revision again returns 200 with the first rejection. Only the reviewer key can call it.","security":[{"reviewerKey":[]}],"parameters":[{"schema":{"type":"string","format":"uuid","description":"The draft id returned by POST /drafts."},"required":true,"description":"The draft id returned by POST /drafts.","name":"id","in":"path"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"revision_id":{"type":"string","format":"uuid","description":"The id of the revision you reviewed: `current_revision.id` from the draft you read. If the agent saved a newer revision since, the request fails with `revision_stale` and nothing is decided."},"reason":{"type":"string","pattern":"[\\p{L}\\p{N}]/u","description":"What the agent must change before the email can be approved. The agent reads it in `latest_review.reason` and writes a new revision."}},"required":["revision_id","reason"],"additionalProperties":false}}}},"responses":{"200":{"description":"The draft, now rejected, with the rejection as `latest_review`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Draft"}}}},"400":{"$ref":"#/components/responses/Error","description":"`validation_error`: A field has the wrong type or format or is over its size limit, the body is not valid JSON, or the body was not sent as JSON"},"401":{"$ref":"#/components/responses/Error","description":"`missing_api_key`: The request has no `Authorization: Bearer <key>` header. `invalid_api_key`: The key in `Authorization` is not one this service issued"},"403":{"$ref":"#/components/responses/Error","description":"`invalid_permission`: The key is valid but not allowed here: agent keys never approve or send, reviewer keys never change drafts"},"404":{"$ref":"#/components/responses/Error","description":"`not_found`: No draft has this id. Check the id from the create response."},"409":{"$ref":"#/components/responses/Error","description":"`revision_stale`: The revision the request names is not the current revision of the draft, usually because another revision was saved first. `invalid_state_transition`: The draft is not in a status this action accepts, such as submitting a draft that was approved. `resource_locked`: Other requests kept changing the draft while this one was being saved"},"422":{"$ref":"#/components/responses/Error","description":"`invalid_parameter`: A path or query parameter has the wrong format, such as a draft `id` that is not a UUID. `missing_required_field`: The body is missing one or more required fields"},"500":{"$ref":"#/components/responses/Error","description":"`internal_server_error`: Something failed inside the service"}}}},"/webhooks/resend":{"post":{"tags":["Webhooks"],"summary":"Receive Resend email events","description":"Resend calls this route; agents and reviewers never do. It takes the email.sent, email.delivered, email.delivery_delayed, email.bounced and email.complained events of the emails this service sent, and records the newest one as `send.last_event` on the draft. A `bounced` or `complained` is never replaced by `sent`, `delivered` or `delivery_delayed`, so a problem with one recipient stays visible. It needs no API key: the `svix-id`, `svix-timestamp` and `svix-signature` headers are checked against the raw body and `RESEND_WEBHOOK_SECRET` before the body is parsed, and a request that fails the check writes nothing. Each event id is processed once, an event older than the recorded one does not replace it, and other event types or emails this service did not send are answered with 200 and ignored, so Resend does not retry them.","parameters":[{"in":"header","name":"svix-id","required":true,"description":"The id of the event. Resend sends the same id again when it retries, so it is processed once.","schema":{"type":"string"}},{"in":"header","name":"svix-timestamp","required":true,"description":"When Resend signed the request, in Unix seconds. A timestamp more than 5 minutes from now is refused.","schema":{"type":"string"}},{"in":"header","name":"svix-signature","required":true,"description":"The Svix signature of the id, the timestamp and the raw body, made with the signing secret of the webhook.","schema":{"type":"string"}}],"requestBody":{"required":true,"description":"The Resend event, read as raw text and verified before it is parsed. Only the fields this service uses are listed; Resend sends more.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ResendEmailEvent"}}}},"responses":{"200":{"description":"The event was received. `outcome` says what the service did with it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebhookReceipt"}}}},"400":{"$ref":"#/components/responses/Error","description":"`validation_error`: A field has the wrong type or format or is over its size limit, the body is not valid JSON, or the body was not sent as JSON"},"401":{"$ref":"#/components/responses/Error","description":"`missing_webhook_signature`: A request to POST /webhooks/resend has no `svix-id`, `svix-timestamp` or `svix-signature` header, so it is not a Resend webhook. `invalid_webhook_signature`: The `svix-signature` of a webhook does not match its body and `RESEND_WEBHOOK_SECRET`, or its `svix-timestamp` is more than 5 minutes from now"},"500":{"$ref":"#/components/responses/Error","description":"`internal_server_error`: Something failed inside the service"},"503":{"$ref":"#/components/responses/Error","description":"`webhook_not_configured`: `RESEND_WEBHOOK_SECRET` is not set, so the service cannot verify Resend webhooks and records no delivery events"}}}}},"webhooks":{}}