@primitivedotdev/sdk 0.13.0 → 0.15.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/api/generated/index.js +1 -1
- package/dist/api/generated/sdk.gen.js +67 -1
- package/dist/api/index.d.ts +2 -2
- package/dist/{api-DvJpdOJ8.js → api-DpATn7LQ.js} +76 -2
- package/dist/{index-ChLFXxTa.d.ts → index-DEY4h3MZ.d.ts} +464 -10
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/dist/oclif/commands/emails-latest.js +131 -0
- package/dist/oclif/commands/send.js +10 -1
- package/dist/oclif/index.js +78 -3
- package/dist/openapi/index.d.ts +6 -0
- package/dist/openapi/openapi.generated.js +395 -47
- package/dist/openapi/operations.generated.js +2395 -98
- package/oclif.manifest.json +212 -13
- package/package.json +3 -3
|
@@ -557,15 +557,9 @@ export const openapiDocument = {
|
|
|
557
557
|
"name": "status",
|
|
558
558
|
"in": "query",
|
|
559
559
|
"schema": {
|
|
560
|
-
"
|
|
561
|
-
"enum": [
|
|
562
|
-
"pending",
|
|
563
|
-
"accepted",
|
|
564
|
-
"completed",
|
|
565
|
-
"rejected"
|
|
566
|
-
]
|
|
560
|
+
"$ref": "#/components/schemas/EmailStatus"
|
|
567
561
|
},
|
|
568
|
-
"description": "Filter by
|
|
562
|
+
"description": "Filter inbound rows by lifecycle status. See `EmailStatus`\nfor what each value means. Note that the webhook delivery\nstate is a SEPARATE lifecycle on the same row; filter by\n`webhook_status` semantics is not currently supported on\nthis endpoint.\n"
|
|
569
563
|
},
|
|
570
564
|
{
|
|
571
565
|
"name": "search",
|
|
@@ -638,7 +632,8 @@ export const openapiDocument = {
|
|
|
638
632
|
],
|
|
639
633
|
"get": {
|
|
640
634
|
"operationId": "getEmail",
|
|
641
|
-
"summary": "Get email
|
|
635
|
+
"summary": "Get inbound email by id",
|
|
636
|
+
"description": "Returns the full record for an inbound email received at one\nof your verified domains, including the parsed text and HTML\nbodies, threading metadata, SMTP envelope detail, webhook\ndelivery state, and a `replies` array for any outbound sends\nrecorded as replies to this inbound.\n\nFor listing inbound emails (with cursor pagination, status\nand date filters, and free-text search), use\n`/emails`. Outbound (sent) email records are NOT returned\nhere; use `/sent-emails/{id}` for those.\n\nThe response carries four sender-shaped fields whose\nmeanings overlap. `from_email` is the canonical \"who sent\nthis\" field for most use cases (parsed bare address from\nthe `From:` header, with a `sender` fallback). `from_header`\nis the raw header including any display name. `sender` and\n`smtp_mail_from` both carry the SMTP envelope MAIL FROM\n(return-path) and are equal by construction; `sender` is\nthe older field name retained for compatibility. See\n`primitive describe emails:get-email | jq '.responseSchema.properties'`\nfor per-field detail.\n",
|
|
642
637
|
"tags": [
|
|
643
638
|
"Emails"
|
|
644
639
|
],
|
|
@@ -1647,6 +1642,150 @@ export const openapiDocument = {
|
|
|
1647
1642
|
}
|
|
1648
1643
|
}
|
|
1649
1644
|
}
|
|
1645
|
+
},
|
|
1646
|
+
"/sent-emails": {
|
|
1647
|
+
"get": {
|
|
1648
|
+
"operationId": "listSentEmails",
|
|
1649
|
+
"summary": "List outbound sent emails",
|
|
1650
|
+
"description": "Returns a paginated list of OUTBOUND emails the caller's\norg has sent via /send-mail (and /emails/{id}/reply, which\nforwards through /send-mail). Includes every recorded\nattempt, including gate-denied attempts that the agent\nnever called and rows still in `queued` state.\n\nFor inbound mail received at your verified domains, see\n/emails. There is no unified send/receive history endpoint;\nthe two surfaces are intentionally separate because the\nunderlying tables, statuses, and lifecycle differ.\n\nEmail bodies (`body_text`, `body_html`) are NOT included on\nlist rows so a 50-row page can't balloon into a multi-MB\nresponse when sends are near the 5MB body cap. Use\n/sent-emails/{id} to fetch a single row with bodies, or\ncross-reference by `client_idempotency_key` if the caller\nalready has the body locally.\n",
|
|
1651
|
+
"tags": [
|
|
1652
|
+
"Sending"
|
|
1653
|
+
],
|
|
1654
|
+
"parameters": [
|
|
1655
|
+
{
|
|
1656
|
+
"$ref": "#/components/parameters/Cursor"
|
|
1657
|
+
},
|
|
1658
|
+
{
|
|
1659
|
+
"$ref": "#/components/parameters/Limit"
|
|
1660
|
+
},
|
|
1661
|
+
{
|
|
1662
|
+
"name": "status",
|
|
1663
|
+
"in": "query",
|
|
1664
|
+
"schema": {
|
|
1665
|
+
"$ref": "#/components/schemas/SentEmailStatus"
|
|
1666
|
+
},
|
|
1667
|
+
"description": "Filter to rows in this status. Useful for polling\nqueued rows that haven't transitioned, auditing\ngate-denied attempts, or listing only successful\ndeliveries.\n"
|
|
1668
|
+
},
|
|
1669
|
+
{
|
|
1670
|
+
"name": "request_id",
|
|
1671
|
+
"in": "query",
|
|
1672
|
+
"schema": {
|
|
1673
|
+
"type": "string",
|
|
1674
|
+
"format": "uuid"
|
|
1675
|
+
},
|
|
1676
|
+
"description": "Filter to the row matching a specific server-issued\n`request_id`. The /send-mail response surfaces\n`request_id` on every send; this lookup lets the\ncaller find the historical row for a given live call\nwithout remembering its `id`.\n"
|
|
1677
|
+
},
|
|
1678
|
+
{
|
|
1679
|
+
"name": "idempotency_key",
|
|
1680
|
+
"in": "query",
|
|
1681
|
+
"schema": {
|
|
1682
|
+
"type": "string",
|
|
1683
|
+
"minLength": 1,
|
|
1684
|
+
"maxLength": 255
|
|
1685
|
+
},
|
|
1686
|
+
"description": "Filter to rows with the given `client_idempotency_key`.\nMultiple rows can share a key (a retry that hit the\nidempotent-replay path returns the same row, but a\nretry with a DIFFERENT canonical payload under the\nsame key is rejected by /send-mail before the row is\nwritten, so duplicates are bounded).\n"
|
|
1687
|
+
},
|
|
1688
|
+
{
|
|
1689
|
+
"name": "date_from",
|
|
1690
|
+
"in": "query",
|
|
1691
|
+
"schema": {
|
|
1692
|
+
"type": "string",
|
|
1693
|
+
"format": "date-time"
|
|
1694
|
+
},
|
|
1695
|
+
"description": "Inclusive lower bound on `created_at`."
|
|
1696
|
+
},
|
|
1697
|
+
{
|
|
1698
|
+
"name": "date_to",
|
|
1699
|
+
"in": "query",
|
|
1700
|
+
"schema": {
|
|
1701
|
+
"type": "string",
|
|
1702
|
+
"format": "date-time"
|
|
1703
|
+
},
|
|
1704
|
+
"description": "Inclusive upper bound on `created_at`."
|
|
1705
|
+
}
|
|
1706
|
+
],
|
|
1707
|
+
"responses": {
|
|
1708
|
+
"200": {
|
|
1709
|
+
"description": "Page of sent-email summaries",
|
|
1710
|
+
"content": {
|
|
1711
|
+
"application/json": {
|
|
1712
|
+
"schema": {
|
|
1713
|
+
"allOf": [
|
|
1714
|
+
{
|
|
1715
|
+
"$ref": "#/components/schemas/ListEnvelope"
|
|
1716
|
+
},
|
|
1717
|
+
{
|
|
1718
|
+
"type": "object",
|
|
1719
|
+
"properties": {
|
|
1720
|
+
"data": {
|
|
1721
|
+
"type": "array",
|
|
1722
|
+
"items": {
|
|
1723
|
+
"$ref": "#/components/schemas/SentEmailSummary"
|
|
1724
|
+
}
|
|
1725
|
+
}
|
|
1726
|
+
}
|
|
1727
|
+
}
|
|
1728
|
+
]
|
|
1729
|
+
}
|
|
1730
|
+
}
|
|
1731
|
+
}
|
|
1732
|
+
},
|
|
1733
|
+
"400": {
|
|
1734
|
+
"$ref": "#/components/responses/ValidationError"
|
|
1735
|
+
},
|
|
1736
|
+
"401": {
|
|
1737
|
+
"$ref": "#/components/responses/Unauthorized"
|
|
1738
|
+
}
|
|
1739
|
+
}
|
|
1740
|
+
}
|
|
1741
|
+
},
|
|
1742
|
+
"/sent-emails/{id}": {
|
|
1743
|
+
"get": {
|
|
1744
|
+
"operationId": "getSentEmail",
|
|
1745
|
+
"summary": "Get a sent email by id",
|
|
1746
|
+
"description": "Returns the full sent-email record by id, including\n`body_text` and `body_html` (omitted from the listing\nendpoint to keep paginated responses small). Use this when\ndiagnosing a specific send, e.g. inspecting the receiver's\nSMTP response on a `bounced` row or pulling the gate\ndenial detail on a `gate_denied` row.\n",
|
|
1747
|
+
"tags": [
|
|
1748
|
+
"Sending"
|
|
1749
|
+
],
|
|
1750
|
+
"parameters": [
|
|
1751
|
+
{
|
|
1752
|
+
"$ref": "#/components/parameters/ResourceId"
|
|
1753
|
+
}
|
|
1754
|
+
],
|
|
1755
|
+
"responses": {
|
|
1756
|
+
"200": {
|
|
1757
|
+
"description": "Sent-email detail",
|
|
1758
|
+
"content": {
|
|
1759
|
+
"application/json": {
|
|
1760
|
+
"schema": {
|
|
1761
|
+
"allOf": [
|
|
1762
|
+
{
|
|
1763
|
+
"$ref": "#/components/schemas/SuccessEnvelope"
|
|
1764
|
+
},
|
|
1765
|
+
{
|
|
1766
|
+
"type": "object",
|
|
1767
|
+
"properties": {
|
|
1768
|
+
"data": {
|
|
1769
|
+
"$ref": "#/components/schemas/SentEmailDetail"
|
|
1770
|
+
}
|
|
1771
|
+
}
|
|
1772
|
+
}
|
|
1773
|
+
]
|
|
1774
|
+
}
|
|
1775
|
+
}
|
|
1776
|
+
}
|
|
1777
|
+
},
|
|
1778
|
+
"400": {
|
|
1779
|
+
"$ref": "#/components/responses/ValidationError"
|
|
1780
|
+
},
|
|
1781
|
+
"401": {
|
|
1782
|
+
"$ref": "#/components/responses/Unauthorized"
|
|
1783
|
+
},
|
|
1784
|
+
"404": {
|
|
1785
|
+
"$ref": "#/components/responses/NotFound"
|
|
1786
|
+
}
|
|
1787
|
+
}
|
|
1788
|
+
}
|
|
1650
1789
|
}
|
|
1651
1790
|
},
|
|
1652
1791
|
"components": {
|
|
@@ -2470,13 +2609,7 @@ export const openapiDocument = {
|
|
|
2470
2609
|
"format": "uuid"
|
|
2471
2610
|
},
|
|
2472
2611
|
"status": {
|
|
2473
|
-
"
|
|
2474
|
-
"enum": [
|
|
2475
|
-
"pending",
|
|
2476
|
-
"accepted",
|
|
2477
|
-
"completed",
|
|
2478
|
-
"rejected"
|
|
2479
|
-
]
|
|
2612
|
+
"$ref": "#/components/schemas/EmailStatus"
|
|
2480
2613
|
},
|
|
2481
2614
|
"sender": {
|
|
2482
2615
|
"type": "string",
|
|
@@ -2515,18 +2648,7 @@ export const openapiDocument = {
|
|
|
2515
2648
|
]
|
|
2516
2649
|
},
|
|
2517
2650
|
"webhook_status": {
|
|
2518
|
-
"
|
|
2519
|
-
"string",
|
|
2520
|
-
"null"
|
|
2521
|
-
],
|
|
2522
|
-
"enum": [
|
|
2523
|
-
"pending",
|
|
2524
|
-
"in_flight",
|
|
2525
|
-
"fired",
|
|
2526
|
-
"failed",
|
|
2527
|
-
"exhausted",
|
|
2528
|
-
null
|
|
2529
|
-
]
|
|
2651
|
+
"$ref": "#/components/schemas/EmailWebhookStatus"
|
|
2530
2652
|
},
|
|
2531
2653
|
"webhook_attempt_count": {
|
|
2532
2654
|
"type": "integer"
|
|
@@ -2598,13 +2720,7 @@ export const openapiDocument = {
|
|
|
2598
2720
|
"description": "HTML body parsed from the inbound MIME, matching the `email.parsed.body_html` field on the webhook payload. Null when the message had no HTML part or parsing failed."
|
|
2599
2721
|
},
|
|
2600
2722
|
"status": {
|
|
2601
|
-
"
|
|
2602
|
-
"enum": [
|
|
2603
|
-
"pending",
|
|
2604
|
-
"accepted",
|
|
2605
|
-
"completed",
|
|
2606
|
-
"rejected"
|
|
2607
|
-
]
|
|
2723
|
+
"$ref": "#/components/schemas/EmailStatus"
|
|
2608
2724
|
},
|
|
2609
2725
|
"domain": {
|
|
2610
2726
|
"type": "string"
|
|
@@ -2642,18 +2758,7 @@ export const openapiDocument = {
|
|
|
2642
2758
|
]
|
|
2643
2759
|
},
|
|
2644
2760
|
"webhook_status": {
|
|
2645
|
-
"
|
|
2646
|
-
"string",
|
|
2647
|
-
"null"
|
|
2648
|
-
],
|
|
2649
|
-
"enum": [
|
|
2650
|
-
"pending",
|
|
2651
|
-
"in_flight",
|
|
2652
|
-
"fired",
|
|
2653
|
-
"failed",
|
|
2654
|
-
"exhausted",
|
|
2655
|
-
null
|
|
2656
|
-
]
|
|
2761
|
+
"$ref": "#/components/schemas/EmailWebhookStatus"
|
|
2657
2762
|
},
|
|
2658
2763
|
"webhook_attempt_count": {
|
|
2659
2764
|
"type": "integer"
|
|
@@ -2865,12 +2970,39 @@ export const openapiDocument = {
|
|
|
2865
2970
|
"subject"
|
|
2866
2971
|
]
|
|
2867
2972
|
},
|
|
2973
|
+
"EmailStatus": {
|
|
2974
|
+
"type": "string",
|
|
2975
|
+
"description": "Lifecycle status of an INBOUND email (a row in the `emails`\ntable). Distinct from `SentEmailStatus`, which describes\nthe OUTBOUND lifecycle (the `sent_emails` table) and uses\na different vocabulary because the lifecycles differ.\nPossible values:\n\n - `pending`: the row was inserted at ingestion (mx_main)\n and has not yet completed the spam / filter / auth\n pipeline. Body and parsed fields are present; webhook\n delivery is not yet scheduled. Most rows transition out\n of `pending` within seconds.\n - `accepted`: the inbound passed the policy gates and is\n queued for webhook delivery. The `webhook_status` field\n tracks the separate webhook-delivery lifecycle from\n this point.\n - `completed`: terminal success. Webhook delivery\n attempted and acknowledged by every active endpoint, OR\n no endpoints are configured, so the row is durably\n archived.\n - `rejected`: terminal failure at ingestion (spam, blocked\n sender, filter rule, malformed). The body and metadata\n are stored for auditing but no webhook fires and the\n row is not repliable.\n\nSee also `webhook_status` (separate enum tracking the\nwebhook-delivery state machine) and `SentEmailStatus` (the\noutbound vocabulary).\n",
|
|
2976
|
+
"enum": [
|
|
2977
|
+
"pending",
|
|
2978
|
+
"accepted",
|
|
2979
|
+
"completed",
|
|
2980
|
+
"rejected"
|
|
2981
|
+
]
|
|
2982
|
+
},
|
|
2983
|
+
"EmailWebhookStatus": {
|
|
2984
|
+
"type": [
|
|
2985
|
+
"string",
|
|
2986
|
+
"null"
|
|
2987
|
+
],
|
|
2988
|
+
"description": "Webhook-delivery state for an inbound email. Tracks a\nSEPARATE lifecycle from the email's `status` field; the\nsame row carries both. Possible values:\n\n - `pending`: ingestion is past `pending` (the email itself\n is `accepted`) but the webhook fan-out has not yet\n started for this row.\n - `in_flight`: at least one delivery attempt is in flight.\n - `fired`: terminal success. Every active endpoint\n acknowledged the delivery (or accepted it after retries).\n - `failed`: terminal partial-failure. At least one endpoint\n exhausted its retry budget; some endpoints may still\n have succeeded.\n - `exhausted`: terminal failure. Every endpoint exhausted\n its retry budget without success.\n - `null`: no endpoints configured, so no webhook lifecycle\n applies.\n\nNote that the value `pending` here does NOT mean the email\nis `pending`; it means the email is past ingestion but\nwebhook delivery has not yet begun. Two overlapping uses\nof the word `pending` for distinct lifecycle phases.\n",
|
|
2989
|
+
"enum": [
|
|
2990
|
+
"pending",
|
|
2991
|
+
"in_flight",
|
|
2992
|
+
"fired",
|
|
2993
|
+
"failed",
|
|
2994
|
+
"exhausted",
|
|
2995
|
+
null
|
|
2996
|
+
]
|
|
2997
|
+
},
|
|
2868
2998
|
"SentEmailStatus": {
|
|
2869
2999
|
"type": "string",
|
|
3000
|
+
"description": "Lifecycle status of a sent_emails row. Possible values:\n\n - `queued`: pre-call INSERT; the outbound agent has not\n yet replied.\n - `submitted_to_agent`: agent accepted; `queue_id` is set.\n - `agent_failed`: agent rejected; `error_code` and\n `error_message` carry the reason.\n - `gate_denied`: a recipient-scope gate denied the send;\n the agent was never called. The `gates` array carries\n the denial detail. /send-mail returns 403 in this case\n so callers see the denial synchronously; /sent-emails\n additionally records the row for historical lookup,\n which is when this status appears in a listing.\n - `unknown`: terminal indeterminate; the on-box log\n poller couldn't classify the receiver's response.\n - `delivered` / `bounced` / `deferred` / `wait_timeout`:\n terminal delivery outcomes (see DeliveryStatus).\n",
|
|
2870
3001
|
"enum": [
|
|
2871
3002
|
"queued",
|
|
2872
3003
|
"submitted_to_agent",
|
|
2873
3004
|
"agent_failed",
|
|
3005
|
+
"gate_denied",
|
|
2874
3006
|
"unknown",
|
|
2875
3007
|
"delivered",
|
|
2876
3008
|
"bounced",
|
|
@@ -2887,6 +3019,217 @@ export const openapiDocument = {
|
|
|
2887
3019
|
"wait_timeout"
|
|
2888
3020
|
]
|
|
2889
3021
|
},
|
|
3022
|
+
"SentEmailSummary": {
|
|
3023
|
+
"type": "object",
|
|
3024
|
+
"description": "List-row projection of a sent-email record. Drops\n`body_text` and `body_html` to keep paginated responses\nsmall; fetch /sent-emails/{id} for the full record with\nbodies.\n",
|
|
3025
|
+
"properties": {
|
|
3026
|
+
"id": {
|
|
3027
|
+
"type": "string",
|
|
3028
|
+
"format": "uuid"
|
|
3029
|
+
},
|
|
3030
|
+
"status": {
|
|
3031
|
+
"$ref": "#/components/schemas/SentEmailStatus"
|
|
3032
|
+
},
|
|
3033
|
+
"status_changed_at": {
|
|
3034
|
+
"type": "string",
|
|
3035
|
+
"format": "date-time",
|
|
3036
|
+
"description": "Timestamp of the most recent status transition.\nPolling clients should treat `status='queued'` AND\n`status_changed_at` older than 5 minutes as\n\"stuck-queued\" (the post-tx UPDATE failed and the\nactual delivery state is recoverable from on-box logs\nvia `queue_id` when populated, or `request_id`).\n"
|
|
3037
|
+
},
|
|
3038
|
+
"created_at": {
|
|
3039
|
+
"type": "string",
|
|
3040
|
+
"format": "date-time"
|
|
3041
|
+
},
|
|
3042
|
+
"updated_at": {
|
|
3043
|
+
"type": "string",
|
|
3044
|
+
"format": "date-time"
|
|
3045
|
+
},
|
|
3046
|
+
"client_idempotency_key": {
|
|
3047
|
+
"type": [
|
|
3048
|
+
"string",
|
|
3049
|
+
"null"
|
|
3050
|
+
],
|
|
3051
|
+
"description": "Effective idempotency key used for this send. If the\ncaller passed the `Idempotency-Key` header, this is\nthat value; otherwise it's a server-derived hash of\nthe canonical request payload.\n"
|
|
3052
|
+
},
|
|
3053
|
+
"content_hash": {
|
|
3054
|
+
"type": "string",
|
|
3055
|
+
"description": "Stable hash of the canonical send payload."
|
|
3056
|
+
},
|
|
3057
|
+
"from_header": {
|
|
3058
|
+
"type": "string",
|
|
3059
|
+
"description": "Raw `From:` header as sent on the wire, including any\ndisplay name (e.g. `\"Acme Support\" <agent@acme.test>`).\n"
|
|
3060
|
+
},
|
|
3061
|
+
"from_address": {
|
|
3062
|
+
"type": "string",
|
|
3063
|
+
"description": "Bare email address parsed from `from_header`."
|
|
3064
|
+
},
|
|
3065
|
+
"to_header": {
|
|
3066
|
+
"type": "string",
|
|
3067
|
+
"description": "Raw `To:` header as sent on the wire, including any\ndisplay name.\n"
|
|
3068
|
+
},
|
|
3069
|
+
"to_address": {
|
|
3070
|
+
"type": "string",
|
|
3071
|
+
"description": "Bare email address parsed from `to_header`."
|
|
3072
|
+
},
|
|
3073
|
+
"subject": {
|
|
3074
|
+
"type": "string"
|
|
3075
|
+
},
|
|
3076
|
+
"body_size_bytes": {
|
|
3077
|
+
"type": "integer",
|
|
3078
|
+
"description": "Total UTF-8 byte length of `body_text` + `body_html`.\nSurfaced on the list endpoint so callers can see \"this\nrow has a 4MB body\" without fetching it.\n"
|
|
3079
|
+
},
|
|
3080
|
+
"content_discarded_at": {
|
|
3081
|
+
"type": [
|
|
3082
|
+
"string",
|
|
3083
|
+
"null"
|
|
3084
|
+
],
|
|
3085
|
+
"format": "date-time",
|
|
3086
|
+
"description": "Timestamp at which the bodies were discarded by an\nentitlement-driven retention policy. Null when bodies\nare still present. The detail endpoint returns\nnull-valued `body_text`/`body_html` for discarded rows.\n"
|
|
3087
|
+
},
|
|
3088
|
+
"message_id": {
|
|
3089
|
+
"type": [
|
|
3090
|
+
"string",
|
|
3091
|
+
"null"
|
|
3092
|
+
],
|
|
3093
|
+
"description": "Wire-level Message-ID assigned to the outbound message\n(RFC 5322). Null on rows that never reached signing\n(queued, gate_denied, agent_failed before signing).\n"
|
|
3094
|
+
},
|
|
3095
|
+
"in_reply_to": {
|
|
3096
|
+
"type": [
|
|
3097
|
+
"string",
|
|
3098
|
+
"null"
|
|
3099
|
+
],
|
|
3100
|
+
"description": "Wire-level In-Reply-To header value, when this send\nwas a reply.\n"
|
|
3101
|
+
},
|
|
3102
|
+
"email_references": {
|
|
3103
|
+
"type": [
|
|
3104
|
+
"string",
|
|
3105
|
+
"null"
|
|
3106
|
+
],
|
|
3107
|
+
"description": "Wire-level References header value, when this send\nwas a reply.\n"
|
|
3108
|
+
},
|
|
3109
|
+
"in_reply_to_email_id": {
|
|
3110
|
+
"type": [
|
|
3111
|
+
"string",
|
|
3112
|
+
"null"
|
|
3113
|
+
],
|
|
3114
|
+
"format": "uuid",
|
|
3115
|
+
"description": "Reference to the inbound `emails.id` that this send\nreplied to, when known. Populated when the caller used\n/emails/{id}/reply or when /send-mail's `in_reply_to`\nmatched a stored inbound message_id in the same org.\n"
|
|
3116
|
+
},
|
|
3117
|
+
"queue_id": {
|
|
3118
|
+
"type": [
|
|
3119
|
+
"string",
|
|
3120
|
+
"null"
|
|
3121
|
+
],
|
|
3122
|
+
"description": "Message identifier assigned by Primitive's outbound\nrelay once the agent accepts the message. Null on\nqueued, gate_denied, and agent_failed rows.\n"
|
|
3123
|
+
},
|
|
3124
|
+
"smtp_response_code": {
|
|
3125
|
+
"type": [
|
|
3126
|
+
"integer",
|
|
3127
|
+
"null"
|
|
3128
|
+
],
|
|
3129
|
+
"description": "Receiver's 3-digit SMTP code (e.g. 250, 550, 451).\nPopulated on terminal delivery statuses; may be null\non a deferred where the agent never got an SMTP-level\nresponse (TCP refused, DNS failed, TLS handshake\nfailed). `smtp_response_text` still carries Postfix's\ndescriptive text in those cases.\n"
|
|
3130
|
+
},
|
|
3131
|
+
"smtp_response_text": {
|
|
3132
|
+
"type": [
|
|
3133
|
+
"string",
|
|
3134
|
+
"null"
|
|
3135
|
+
],
|
|
3136
|
+
"description": "Free-form text portion of the receiver's SMTP\nresponse. The most useful debugging signal on a\n`bounced` or `deferred` row.\n"
|
|
3137
|
+
},
|
|
3138
|
+
"smtp_enhanced_status_code": {
|
|
3139
|
+
"type": [
|
|
3140
|
+
"string",
|
|
3141
|
+
"null"
|
|
3142
|
+
],
|
|
3143
|
+
"description": "RFC 3463 enhanced status code (e.g. `5.1.1` for \"Bad\ndestination mailbox address\"). Distinct from\n`smtp_response_code`: the basic 3-digit code is coarse\n(550 = \"permanent failure\"), the enhanced code is\nfiner-grained.\n"
|
|
3144
|
+
},
|
|
3145
|
+
"dkim_selector": {
|
|
3146
|
+
"type": [
|
|
3147
|
+
"string",
|
|
3148
|
+
"null"
|
|
3149
|
+
],
|
|
3150
|
+
"description": "DKIM selector used to sign the outbound message.\nPublic DNS data; useful for diagnosing why a downstream\nverifier rejected the signature.\n"
|
|
3151
|
+
},
|
|
3152
|
+
"dkim_domain": {
|
|
3153
|
+
"type": [
|
|
3154
|
+
"string",
|
|
3155
|
+
"null"
|
|
3156
|
+
],
|
|
3157
|
+
"description": "DKIM signing domain."
|
|
3158
|
+
},
|
|
3159
|
+
"error_code": {
|
|
3160
|
+
"type": [
|
|
3161
|
+
"string",
|
|
3162
|
+
"null"
|
|
3163
|
+
],
|
|
3164
|
+
"description": "Stable public error code on `agent_failed` rows. The\nagent's internal codes are remapped to a stable public\ntaxonomy (see `publicAgentError` in the server) so this\nfield is safe to branch on across agent versions.\n"
|
|
3165
|
+
},
|
|
3166
|
+
"error_message": {
|
|
3167
|
+
"type": [
|
|
3168
|
+
"string",
|
|
3169
|
+
"null"
|
|
3170
|
+
],
|
|
3171
|
+
"description": "Free-form error message accompanying `error_code`."
|
|
3172
|
+
},
|
|
3173
|
+
"gates": {
|
|
3174
|
+
"type": [
|
|
3175
|
+
"array",
|
|
3176
|
+
"null"
|
|
3177
|
+
],
|
|
3178
|
+
"items": {
|
|
3179
|
+
"$ref": "#/components/schemas/GateDenial"
|
|
3180
|
+
},
|
|
3181
|
+
"description": "Gate-denial detail on `gate_denied` rows. Mirrors the\nsynchronous /send-mail 403 contract so a caller's\nGateDenial handler is the same across live denies and\nhistorical lookups. Null on every other status.\n"
|
|
3182
|
+
},
|
|
3183
|
+
"request_id": {
|
|
3184
|
+
"type": [
|
|
3185
|
+
"string",
|
|
3186
|
+
"null"
|
|
3187
|
+
],
|
|
3188
|
+
"description": "Server-issued request identifier from the original\n/send-mail call. Surfaced as the `X-Request-Id`\nresponse header on the live send and recorded here\nfor support escalation.\n"
|
|
3189
|
+
}
|
|
3190
|
+
},
|
|
3191
|
+
"required": [
|
|
3192
|
+
"id",
|
|
3193
|
+
"status",
|
|
3194
|
+
"status_changed_at",
|
|
3195
|
+
"created_at",
|
|
3196
|
+
"updated_at",
|
|
3197
|
+
"content_hash",
|
|
3198
|
+
"from_header",
|
|
3199
|
+
"from_address",
|
|
3200
|
+
"to_header",
|
|
3201
|
+
"to_address",
|
|
3202
|
+
"subject",
|
|
3203
|
+
"body_size_bytes"
|
|
3204
|
+
]
|
|
3205
|
+
},
|
|
3206
|
+
"SentEmailDetail": {
|
|
3207
|
+
"description": "Full sent-email record, including `body_text` and\n`body_html`. Returned by /sent-emails/{id}.\n",
|
|
3208
|
+
"allOf": [
|
|
3209
|
+
{
|
|
3210
|
+
"$ref": "#/components/schemas/SentEmailSummary"
|
|
3211
|
+
},
|
|
3212
|
+
{
|
|
3213
|
+
"type": "object",
|
|
3214
|
+
"properties": {
|
|
3215
|
+
"body_text": {
|
|
3216
|
+
"type": [
|
|
3217
|
+
"string",
|
|
3218
|
+
"null"
|
|
3219
|
+
],
|
|
3220
|
+
"description": "Plain-text body sent on the wire. Null when the\nsend carried only an HTML body, or when bodies have\nbeen discarded post-send (`content_discarded_at`\nset).\n"
|
|
3221
|
+
},
|
|
3222
|
+
"body_html": {
|
|
3223
|
+
"type": [
|
|
3224
|
+
"string",
|
|
3225
|
+
"null"
|
|
3226
|
+
],
|
|
3227
|
+
"description": "HTML body sent on the wire. Null when the send\ncarried only a plain-text body, or when bodies\nhave been discarded post-send.\n"
|
|
3228
|
+
}
|
|
3229
|
+
}
|
|
3230
|
+
}
|
|
3231
|
+
]
|
|
3232
|
+
},
|
|
2890
3233
|
"ReplyInput": {
|
|
2891
3234
|
"type": "object",
|
|
2892
3235
|
"additionalProperties": false,
|
|
@@ -2922,6 +3265,10 @@ export const openapiDocument = {
|
|
|
2922
3265
|
"status": {
|
|
2923
3266
|
"$ref": "#/components/schemas/SentEmailStatus"
|
|
2924
3267
|
},
|
|
3268
|
+
"from": {
|
|
3269
|
+
"type": "string",
|
|
3270
|
+
"description": "Bare from-address actually written on the wire. Echoed\non every success branch so callers can confirm what\nwent out, particularly useful for the /emails/{id}/reply\npath where `from` is server-derived from the inbound's\nrecipient when the caller doesn't override.\n\nFor sends where the caller passed a from-header that\nincluded a display name (e.g. `\"Acme Support\" <support@acme.test>`),\nthis field is the parsed bare address (`support@acme.test`).\nThe display name was sent on the wire intact; this field\njust makes the address easy to compare against allowlists.\n"
|
|
3271
|
+
},
|
|
2925
3272
|
"queue_id": {
|
|
2926
3273
|
"type": [
|
|
2927
3274
|
"string",
|
|
@@ -2977,6 +3324,7 @@ export const openapiDocument = {
|
|
|
2977
3324
|
"required": [
|
|
2978
3325
|
"id",
|
|
2979
3326
|
"status",
|
|
3327
|
+
"from",
|
|
2980
3328
|
"queue_id",
|
|
2981
3329
|
"accepted",
|
|
2982
3330
|
"rejected",
|