{"openapi":"3.1.1","info":{"title":"RelyPost Email API","version":"v1","summary":"Transactional email, attachments, domains and webhooks","description":"Integrate RelyPost transactional email with cURL, Node.js or Python. Complete REST API reference for HTML email, attachments, scheduling, delivery status and webhooks. Reviewed 2026-09-14. Activation, verified domain and active API sender are required. Default limits may differ by deployment; consult your workspace Billing settings.","contact":{"name":"RelyPost support","email":"support@relypost.com","url":"https://relypost.com/support"}},"servers":[{"url":"https://api.relypost.com/v1"}],"externalDocs":{"description":"Complete integration guide and examples","url":"https://relypost.com/docs"},"tags":[{"name":"emails"},{"name":"domains"},{"name":"attachments"},{"name":"webhooks"}],"paths":{"/emails":{"post":{"operationId":"post-emails","tags":["emails"],"summary":"POST /emails","description":"Queue one message. Requires Idempotency-Key (8–200 characters). Returns 202; save the id for tracking. Required API key scope: emails:send.","externalDocs":{"url":"https://relypost.com/docs#post-emails"},"security":[{"bearerAuth":[]}],"x-required-scopes":["emails:send"],"parameters":[{"name":"Idempotency-Key","in":"header","required":true,"schema":{"type":"string","minLength":8,"maxLength":200},"description":"Stable key per application event, scoped to your organization. Reuse the identical payload and key after timeouts; changed content returns 409."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmailInput"},"example":{"from":"hello@your-domain.com","to":["customer@example.com"],"subject":"Your order confirmation","text":"Thank you for your order."}}}},"responses":{"202":{"description":"Accepted into the sending queue; not proof of delivery. An idempotent replay may return a later state.","headers":{"X-Request-Id":{"description":"Support correlation ID.","schema":{"type":"string","format":"uuid"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/QueuedEmail"},"example":{"id":"a19f458e-a915-4aac-8ea1-8c859b41d934","state":"queued","revision":1,"scheduled_at":"2026-09-14T12:00:00.000Z"}}}},"default":{"description":"Error; see error.code and error.requestId. HTTP 400 validation; 401 authentication; 402 billing; 403 authorization/capacity; 404 missing/expired resource; 409 conflict/quota; 413 size; 415 JSON required; 422 suppression; 429 rate limit; 5xx temporary failure or disabled service. Some errors apply only to particular operations.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/emails/{id}":{"get":{"operationId":"get-emails-id","tags":["emails"],"summary":"GET /emails/{id}","description":"Read one API message from this organization within your plan’s log-retention window. Use the UUID returned by POST, not the RFC Message-ID. Required API key scope: emails:read.","externalDocs":{"url":"https://relypost.com/docs#get-emails-id"},"security":[{"bearerAuth":[]}],"x-required-scopes":["emails:read"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"},"description":"Resource UUID belonging to your organization."}],"responses":{"200":{"description":"Success","headers":{"X-Request-Id":{"description":"Support correlation ID.","schema":{"type":"string","format":"uuid"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmailStatus"},"example":{"id":"a19f458e-a915-4aac-8ea1-8c859b41d934","state":"submitted","message_id":"<message@mail01.relypost.com>","created_at":"2026-09-14T12:00:00.000Z","scheduled_at":"2026-09-14T12:00:00.000Z","submitted_at":"2026-09-14T12:00:01.000Z","smtp_code":"250","diagnostic":"Accepted by submission server","recipients":[{"address":"customer@example.com","kind":"to","state":"accepted","enhanced_status":"2.0.0","remote_response":"status=sent (250 accepted)","observed_at":"2026-09-14T12:00:02.000Z"}],"recipient_retry":null,"events":[{"type":"email.queued","created_at":"2026-09-14T12:00:00.000Z","details":{}}]}}}},"default":{"description":"Error; see error.code and error.requestId. HTTP 400 validation; 401 authentication; 402 billing; 403 authorization/capacity; 404 missing/expired resource; 409 conflict/quota; 413 size; 415 JSON required; 422 suppression; 429 rate limit; 5xx temporary failure or disabled service. Some errors apply only to particular operations.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/domains":{"get":{"operationId":"get-domains","tags":["domains"],"summary":"GET /domains","description":"List your organization’s domains. This API reads domains; add or verify them in Developer → Domains. Required API key scope: domains:read.","externalDocs":{"url":"https://relypost.com/docs#get-domains"},"security":[{"bearerAuth":[]}],"x-required-scopes":["domains:read"],"parameters":[],"responses":{"200":{"description":"Success","headers":{"X-Request-Id":{"description":"Support correlation ID.","schema":{"type":"string","format":"uuid"}}},"content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/Domain"}},"example":[{"id":"a19f458e-a915-4aac-8ea1-8c859b41d934","name":"your-domain.com","status":"active","verified_at":"2026-09-14T10:00:00.000Z"}]}}},"default":{"description":"Error; see error.code and error.requestId. HTTP 400 validation; 401 authentication; 402 billing; 403 authorization/capacity; 404 missing/expired resource; 409 conflict/quota; 413 size; 415 JSON required; 422 suppression; 429 rate limit; 5xx temporary failure or disabled service. Some errors apply only to particular operations.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/domains/{id}":{"get":{"operationId":"get-domains-id","tags":["domains"],"summary":"GET /domains/{id}","description":"Read a domain’s status and DNS configuration. Returns id, name, status, verified_at, dkim_selector, dkim_txt and dns_state. Required API key scope: domains:read.","externalDocs":{"url":"https://relypost.com/docs#get-domains-id"},"security":[{"bearerAuth":[]}],"x-required-scopes":["domains:read"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"},"description":"Resource UUID belonging to your organization."}],"responses":{"200":{"description":"Success","headers":{"X-Request-Id":{"description":"Support correlation ID.","schema":{"type":"string","format":"uuid"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DomainDetails"},"example":{"id":"a19f458e-a915-4aac-8ea1-8c859b41d934","name":"your-domain.com","status":"active","verified_at":"2026-09-14T10:00:00.000Z","dkim_selector":"dkim","dkim_txt":"v=DKIM1; k=rsa; p=YOUR_PUBLIC_KEY","dns_state":[]}}}},"default":{"description":"Error; see error.code and error.requestId. HTTP 400 validation; 401 authentication; 402 billing; 403 authorization/capacity; 404 missing/expired resource; 409 conflict/quota; 413 size; 415 JSON required; 422 suppression; 429 rate limit; 5xx temporary failure or disabled service. Some errors apply only to particular operations.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/attachments":{"post":{"operationId":"post-attachments","tags":["attachments"],"summary":"POST /attachments","description":"Reserve an upload; returns 201. id is the eventual attachment ID; sessionId is used for uploading/finalizing. For multipart:false, the response also includes url and fields. Required API key scope: attachments:write.","externalDocs":{"url":"https://relypost.com/docs#post-attachments"},"security":[{"bearerAuth":[]}],"x-required-scopes":["attachments:write"],"parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AttachmentInput"},"example":{"name":"receipt.pdf","size":12345,"type":"application/pdf","multipart":false}}}},"responses":{"201":{"description":"Success","headers":{"X-Request-Id":{"description":"Support correlation ID.","schema":{"type":"string","format":"uuid"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AttachmentReservation"},"example":{"id":"a19f458e-a915-4aac-8ea1-8c859b41d934","sessionId":"94f3e2c8-ff6e-45cf-90ef-8b037111ae64","multipart":false,"url":"https://your-signed-storage-url.example","fields":{"key":"temporary/…","policy":"…","x-amz-signature":"…"}}}}},"default":{"description":"Error; see error.code and error.requestId. HTTP 400 validation; 401 authentication; 402 billing; 403 authorization/capacity; 404 missing/expired resource; 409 conflict/quota; 413 size; 415 JSON required; 422 suppression; 429 rate limit; 5xx temporary failure or disabled service. Some errors apply only to particular operations.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/attachments/{sessionId}/part":{"post":{"operationId":"post-attachments-sessionid-part","tags":["attachments"],"summary":"POST /attachments/{sessionId}/part","description":"For multipart uploads only: get a signed PUT URL for a 1-based part number. Upload exactly that part’s bytes to the URL and save its ETag. Required API key scope: attachments:write.","externalDocs":{"url":"https://relypost.com/docs#post-attachments-sessionid-part"},"security":[{"bearerAuth":[]}],"x-required-scopes":["attachments:write"],"parameters":[{"name":"sessionId","in":"path","required":true,"schema":{"type":"string","format":"uuid"},"description":"Resource UUID belonging to your organization."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadPart"},"example":{"part":1}}}},"responses":{"200":{"description":"Success","headers":{"X-Request-Id":{"description":"Support correlation ID.","schema":{"type":"string","format":"uuid"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadPartUrl"},"example":{"url":"https://your-signed-storage-url.example/part"}}}},"default":{"description":"Error; see error.code and error.requestId. HTTP 400 validation; 401 authentication; 402 billing; 403 authorization/capacity; 404 missing/expired resource; 409 conflict/quota; 413 size; 415 JSON required; 422 suppression; 429 rate limit; 5xx temporary failure or disabled service. Some errors apply only to particular operations.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/attachments/{sessionId}/finalize":{"post":{"operationId":"post-attachments-sessionid-finalize","tags":["attachments"],"summary":"POST /attachments/{sessionId}/finalize","description":"Verify and scan the upload. Single uploads use parts:[]; multipart uploads use ordered {PartNumber,ETag} entries. Only state:ready can be attached to email. Required API key scope: attachments:write.","externalDocs":{"url":"https://relypost.com/docs#post-attachments-sessionid-finalize"},"security":[{"bearerAuth":[]}],"x-required-scopes":["attachments:write"],"parameters":[{"name":"sessionId","in":"path","required":true,"schema":{"type":"string","format":"uuid"},"description":"Resource UUID belonging to your organization."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/FinalizeInput"},"example":{"parts":[]}}}},"responses":{"200":{"description":"Success","headers":{"X-Request-Id":{"description":"Support correlation ID.","schema":{"type":"string","format":"uuid"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/FinalizedAttachment"},"example":{"id":"a19f458e-a915-4aac-8ea1-8c859b41d934","state":"ready"}}}},"default":{"description":"Error; see error.code and error.requestId. HTTP 400 validation; 401 authentication; 402 billing; 403 authorization/capacity; 404 missing/expired resource; 409 conflict/quota; 413 size; 415 JSON required; 422 suppression; 429 rate limit; 5xx temporary failure or disabled service. Some errors apply only to particular operations.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/webhooks":{"get":{"operationId":"get-webhooks","tags":["webhooks"],"summary":"GET /webhooks","description":"List endpoints. Returns id, url, enabled, failures and created_at. Secrets are not returned. Required API key scope: webhooks:manage.","externalDocs":{"url":"https://relypost.com/docs#get-webhooks"},"security":[{"bearerAuth":[]}],"x-required-scopes":["webhooks:manage"],"parameters":[],"responses":{"200":{"description":"Success","headers":{"X-Request-Id":{"description":"Support correlation ID.","schema":{"type":"string","format":"uuid"}}},"content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/WebhookEndpoint"}},"example":[{"id":"a19f458e-a915-4aac-8ea1-8c859b41d934","url":"https://your-app.com/webhooks/relypost","enabled":true,"failures":0,"created_at":"2026-09-14T12:00:00.000Z"}]}}},"default":{"description":"Error; see error.code and error.requestId. HTTP 400 validation; 401 authentication; 402 billing; 403 authorization/capacity; 404 missing/expired resource; 409 conflict/quota; 413 size; 415 JSON required; 422 suppression; 429 rate limit; 5xx temporary failure or disabled service. Some errors apply only to particular operations.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"post":{"operationId":"post-webhooks","tags":["webhooks"],"summary":"POST /webhooks","description":"Register a public HTTPS endpoint on port 443, without URL credentials or a fragment. Returns 201 and a secret shown only once. No event-selection field is supported. Required API key scope: webhooks:manage.","externalDocs":{"url":"https://relypost.com/docs#post-webhooks"},"security":[{"bearerAuth":[]}],"x-required-scopes":["webhooks:manage"],"parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebhookInput"},"example":{"url":"https://your-app.com/webhooks/relypost"}}}},"responses":{"201":{"description":"Success","headers":{"X-Request-Id":{"description":"Support correlation ID.","schema":{"type":"string","format":"uuid"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebhookCreated"},"example":{"id":"a19f458e-a915-4aac-8ea1-8c859b41d934","secret":"SAVE_THE_ONE_TIME_SECRET"}}}},"default":{"description":"Error; see error.code and error.requestId. HTTP 400 validation; 401 authentication; 402 billing; 403 authorization/capacity; 404 missing/expired resource; 409 conflict/quota; 413 size; 415 JSON required; 422 suppression; 429 rate limit; 5xx temporary failure or disabled service. Some errors apply only to particular operations.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/webhooks/{id}":{"patch":{"operationId":"patch-webhooks-id","tags":["webhooks"],"summary":"PATCH /webhooks/{id}","description":"Enable or disable an existing endpoint. This also resets its failure counter. Required API key scope: webhooks:manage.","externalDocs":{"url":"https://relypost.com/docs#patch-webhooks-id"},"security":[{"bearerAuth":[]}],"x-required-scopes":["webhooks:manage"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"},"description":"Resource UUID belonging to your organization."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebhookUpdate"},"example":{"enabled":true}}}},"responses":{"200":{"description":"Success","headers":{"X-Request-Id":{"description":"Support correlation ID.","schema":{"type":"string","format":"uuid"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Ok"},"example":{"ok":true}}}},"default":{"description":"Error; see error.code and error.requestId. HTTP 400 validation; 401 authentication; 402 billing; 403 authorization/capacity; 404 missing/expired resource; 409 conflict/quota; 413 size; 415 JSON required; 422 suppression; 429 rate limit; 5xx temporary failure or disabled service. Some errors apply only to particular operations.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/webhooks/{id}/deliveries":{"get":{"operationId":"get-webhooks-id-deliveries","tags":["webhooks"],"summary":"GET /webhooks/{id}/deliveries","description":"Read up to 100 webhook delivery records. Fields: id, event_id, state, attempts, last_status and next_attempt_at. This endpoint has no pagination parameters. Required API key scope: webhooks:manage.","externalDocs":{"url":"https://relypost.com/docs#get-webhooks-id-deliveries"},"security":[{"bearerAuth":[]}],"x-required-scopes":["webhooks:manage"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"},"description":"Resource UUID belonging to your organization."}],"responses":{"200":{"description":"Success","headers":{"X-Request-Id":{"description":"Support correlation ID.","schema":{"type":"string","format":"uuid"}}},"content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/WebhookDelivery"}},"example":[{"id":"94f3e2c8-ff6e-45cf-90ef-8b037111ae64","event_id":"a19f458e-a915-4aac-8ea1-8c859b41d934","state":"pending","attempts":0,"last_status":null,"next_attempt_at":"2026-09-14T12:00:00.000Z"}]}}},"default":{"description":"Error; see error.code and error.requestId. HTTP 400 validation; 401 authentication; 402 billing; 403 authorization/capacity; 404 missing/expired resource; 409 conflict/quota; 413 size; 415 JSON required; 422 suppression; 429 rate limit; 5xx temporary failure or disabled service. Some errors apply only to particular operations.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/webhooks/{id}/retry":{"post":{"operationId":"post-webhooks-id-retry","tags":["webhooks"],"summary":"POST /webhooks/{id}/retry","description":"Requeue an existing delivery using its delivery-record id. Expired delivery payloads cannot be retried. This retries the webhook notification, not the email. Required API key scope: webhooks:manage.","externalDocs":{"url":"https://relypost.com/docs#post-webhooks-id-retry"},"security":[{"bearerAuth":[]}],"x-required-scopes":["webhooks:manage"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"},"description":"Resource UUID belonging to your organization."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebhookRetry"},"example":{"deliveryId":"94f3e2c8-ff6e-45cf-90ef-8b037111ae64"}}}},"responses":{"200":{"description":"Success","headers":{"X-Request-Id":{"description":"Support correlation ID.","schema":{"type":"string","format":"uuid"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Ok"},"example":{"ok":true}}}},"default":{"description":"Error; see error.code and error.requestId. HTTP 400 validation; 401 authentication; 402 billing; 403 authorization/capacity; 404 missing/expired resource; 409 conflict/quota; 413 size; 415 JSON required; 422 suppression; 429 rate limit; 5xx temporary failure or disabled service. Some errors apply only to particular operations.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}}},"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"rp_live_…","description":"Use a server-side API key. Available scopes: emails:send, emails:read, domains:read, attachments:write, webhooks:manage. Required scopes are described on each operation; this is not OAuth."}},"schemas":{"EmailInput":{"type":"object","properties":{"from":{"type":"string","maxLength":254,"format":"email","pattern":"^(?!\\.)(?!.*\\.\\.)([A-Za-z0-9_'+\\-\\.]*)[A-Za-z0-9_+-]@([A-Za-z0-9][A-Za-z0-9\\-]*\\.)+[A-Za-z]{2,}$"},"to":{"minItems":1,"maxItems":100,"type":"array","items":{"type":"string","maxLength":254,"format":"email","pattern":"^(?!\\.)(?!.*\\.\\.)([A-Za-z0-9_'+\\-\\.]*)[A-Za-z0-9_+-]@([A-Za-z0-9][A-Za-z0-9\\-]*\\.)+[A-Za-z]{2,}$"}},"cc":{"maxItems":100,"type":"array","items":{"type":"string","maxLength":254,"format":"email","pattern":"^(?!\\.)(?!.*\\.\\.)([A-Za-z0-9_'+\\-\\.]*)[A-Za-z0-9_+-]@([A-Za-z0-9][A-Za-z0-9\\-]*\\.)+[A-Za-z]{2,}$"}},"bcc":{"maxItems":100,"type":"array","items":{"type":"string","maxLength":254,"format":"email","pattern":"^(?!\\.)(?!.*\\.\\.)([A-Za-z0-9_'+\\-\\.]*)[A-Za-z0-9_+-]@([A-Za-z0-9][A-Za-z0-9\\-]*\\.)+[A-Za-z]{2,}$"}},"reply_to":{"type":"string","maxLength":254,"format":"email","pattern":"^(?!\\.)(?!.*\\.\\.)([A-Za-z0-9_'+\\-\\.]*)[A-Za-z0-9_+-]@([A-Za-z0-9][A-Za-z0-9\\-]*\\.)+[A-Za-z]{2,}$"},"subject":{"type":"string","maxLength":998,"pattern":"^[^\\r\\n]*$"},"text":{"default":"","type":"string","maxLength":500000},"html":{"type":"string","maxLength":500000},"attachments":{"default":[],"maxItems":20,"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"cid":{"type":"string","pattern":"^[a-zA-Z0-9_.@-]{1,100}$"}},"required":["id"]}},"headers":{"default":{},"type":"object","propertyNames":{"type":"string","pattern":"^X-[A-Za-z0-9-]{1,60}$"},"additionalProperties":{"type":"string","maxLength":500,"pattern":"^[^\\r\\n]*$"}},"tags":{"default":[],"maxItems":10,"type":"array","items":{"type":"string","maxLength":50}},"metadata":{"default":{},"type":"object","propertyNames":{"type":"string","maxLength":50},"additionalProperties":{"type":"string","maxLength":500}},"scheduled_at":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"},"in_reply_to":{"type":"string","maxLength":998,"pattern":"^<[^<>\\s]+@[^<>\\s]+>$"},"references":{"default":[],"maxItems":30,"type":"array","items":{"type":"string","maxLength":998,"pattern":"^<[^<>\\s]+@[^<>\\s]+>$"}},"priority":{"default":"normal","type":"string","enum":["high","normal","low"]}},"required":["from","to","subject"],"additionalProperties":false,"description":"Unknown top-level properties are rejected. Addresses are normalized to lowercase. Combined recipients default to 20; metadata accepts at most 20 keys. Requires an active API sender on a verified API-enrolled domain. scheduled_at must be no more than 365 days ahead. Null is not accepted for optional inputs. MIME size, billing and suppression checks also apply."},"AttachmentInput":{"type":"object","properties":{"name":{"type":"string","minLength":1,"maxLength":180,"pattern":"^[^/\\\\\\x00-\\x1f]+$"},"size":{"type":"integer","exclusiveMinimum":0,"maximum":9007199254740991},"type":{"type":"string","maxLength":120,"pattern":"^[\\w.+-]+\\/[\\w.+-]+$"},"purpose":{"default":"files","type":"string","enum":["files","drafts","scheduled","api-attachments","exports","imports","avatars"]},"folder":{"default":"/","type":"string","maxLength":500},"multipart":{"default":false,"type":"boolean"}},"required":["name","size","type"],"description":"Upload bytes separately to signed storage. purpose is always overridden to api-attachments; omit it. folder defaults to / and must not contain . or .. segments. Default file limit is 100 MiB, subject to storage quota. MIME email limit defaults to 25 MiB including encoding."},"QueuedEmail":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"state":{"type":"string"},"revision":{"type":"integer"},"scheduled_at":{"type":"string","format":"date-time"}},"required":["id","state","revision","scheduled_at"]},"EmailStatus":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"state":{"type":"string"},"message_id":{"anyOf":[{"type":"string"},{"type":"null"}]},"created_at":{"type":"string","format":"date-time"},"submitted_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}]},"scheduled_at":{"type":"string","format":"date-time"},"smtp_code":{"anyOf":[{"type":"string"},{"type":"null"}]},"diagnostic":{"anyOf":[{"type":"string"},{"type":"null"}]},"recipients":{"type":"array","items":{"type":"object","properties":{"address":{"type":"string"},"kind":{"type":"string","enum":["to","cc","bcc"]},"state":{"type":"string"},"enhanced_status":{"anyOf":[{"type":"string"},{"type":"null"}]},"remote_response":{"anyOf":[{"type":"string"},{"type":"null"}]},"observed_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}]}},"required":["address","kind","state","enhanced_status","remote_response","observed_at"]}},"recipient_retry":{"anyOf":[{"type":"object","properties":{"state":{"type":"string"},"attempts":{"type":"integer"},"next_attempt_at":{"type":"string","format":"date-time"},"error_code":{"anyOf":[{"type":"string"},{"type":"null"}]}},"required":["state","attempts","next_attempt_at","error_code"]},{"type":"null"}]},"events":{"type":"array","items":{"type":"object","properties":{"type":{"type":"string"},"created_at":{"type":"string","format":"date-time"},"details":{"type":"object","additionalProperties":true}},"required":["type","created_at","details"]}}},"required":["id","state","message_id","created_at","submitted_at","scheduled_at","smtp_code","diagnostic","recipients","recipient_retry","events"]},"Domain":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"name":{"type":"string"},"status":{"type":"string"},"verified_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}]}},"required":["id","name","status","verified_at"]},"DomainDetails":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"name":{"type":"string"},"status":{"type":"string"},"verified_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}]},"dkim_selector":{"anyOf":[{"type":"string"},{"type":"null"}]},"dkim_txt":{"anyOf":[{"type":"string"},{"type":"null"}]},"dns_state":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["id","name","status","verified_at","dkim_selector","dkim_txt","dns_state"]},"AttachmentReservation":{"oneOf":[{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"sessionId":{"type":"string","format":"uuid"},"multipart":{"const":false,"type":"boolean"},"url":{"type":"string","format":"uri"},"fields":{"type":"object","additionalProperties":{"type":"string"}}},"required":["id","sessionId","multipart","url","fields"]},{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"sessionId":{"type":"string","format":"uuid"},"multipart":{"const":true,"type":"boolean"},"partSize":{"type":"integer","const":5242880},"parts":{"type":"integer","minimum":1}},"required":["id","sessionId","multipart","partSize","parts"]}]},"UploadPart":{"type":"object","properties":{"part":{"type":"integer","exclusiveMinimum":0,"maximum":205}},"required":["part"]},"UploadPartUrl":{"type":"object","properties":{"url":{"type":"string","format":"uri"}},"required":["url"]},"FinalizeInput":{"type":"object","properties":{"parts":{"default":[],"maxItems":205,"type":"array","items":{"type":"object","properties":{"PartNumber":{"type":"integer","exclusiveMinimum":0,"maximum":9007199254740991},"ETag":{"type":"string","minLength":1,"maxLength":200}},"required":["PartNumber","ETag"]}}}},"FinalizedAttachment":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"state":{"type":"string","description":"Only ready files can be attached. A repeat finalize can return the existing file state."}},"required":["id","state"]},"WebhookInput":{"type":"object","properties":{"url":{"type":"string","maxLength":2000,"format":"uri"}},"required":["url"]},"WebhookUpdate":{"type":"object","properties":{"enabled":{"type":"boolean"}},"required":["enabled"]},"WebhookRetry":{"type":"object","properties":{"deliveryId":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"}},"required":["deliveryId"]},"WebhookCreated":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"secret":{"type":"string","description":"Shown only on creation. Store securely on your server."}},"required":["id","secret"]},"WebhookEndpoint":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"url":{"type":"string"},"enabled":{"type":"boolean"},"failures":{"type":"integer"},"created_at":{"type":"string","format":"date-time"}},"required":["id","url","enabled","failures","created_at"]},"WebhookDelivery":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"event_id":{"type":"string","format":"uuid"},"state":{"type":"string"},"attempts":{"type":"integer"},"last_status":{"anyOf":[{"type":"integer"},{"type":"null"}]},"next_attempt_at":{"type":"string","format":"date-time"}},"required":["id","event_id","state","attempts","last_status","next_attempt_at"]},"WebhookEvent":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"type":{"type":"string","description":"Known email events: email.queued, email.submitted, email.deferred, email.uncertain, email.rejected, email.recipient_accepted, email.recipient_deferred, email.recipient_resubmitted, email.bounced, email.submission_recovered, email.complained. Organization events and future event types may also arrive; do not reject unknown types."},"created_at":{"type":"string","format":"date-time"},"data":{"type":"object","additionalProperties":true,"description":"Event-specific details. For email events, id is the message UUID; other keys depend on the event.","properties":{"id":{"type":"string","format":"uuid"}}}},"required":["id","type","created_at","data"]},"Error":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"requestId":{"type":"string","format":"uuid"},"fields":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"message":{"type":"string"}},"required":["path","message"]}}},"required":["code","message","requestId"]}},"required":["error"]},"Ok":{"type":"object","properties":{"ok":{"const":true,"type":"boolean"}},"required":["ok"]}}},"webhooks":{"organizationEvent":{"post":{"operationId":"receive-organization-event","summary":"Receive a signed organization event at your registered HTTPS endpoint","security":[],"description":"RelyPost sends this request to your server. Verify HMAC-SHA256 hex over webhook-id.webhook-timestamp.rawBody using your webhook secret before parsing JSON. Reject timestamps outside a five-minute window. Deduplicate event IDs durably; notifications may be repeated or arrive out of order. Return 2xx after durable acceptance. Requests do not follow redirects. Automatic attempts are bounded; repeated failures can disable the endpoint. See the guide for retry and re-enable instructions.","parameters":[{"name":"webhook-id","in":"header","required":true,"schema":{"type":"string"},"description":"Event UUID, also the payload id; not the delivery-record UUID."},{"name":"webhook-timestamp","in":"header","required":true,"schema":{"type":"string"},"description":"Unix timestamp in seconds."},{"name":"webhook-signature","in":"header","required":true,"schema":{"type":"string"},"description":"Hex HMAC-SHA256 signature."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebhookEvent"}}}},"responses":{"2XX":{"description":"Event accepted durably, including an already processed duplicate."},"default":{"description":"Non-2xx responses are treated as delivery failures."}}}}}}