{
  "openapi": "3.1.0",
  "info": {
    "title": "Trendly Partner API",
    "version": "1.0.0",
    "summary": "Report affiliate orders to Trendly and read the codes attached to them.",
    "description": "Trendly runs a brand's affiliate program: creators join it, the brand approves them, each approved creator gets a personal discount code, and every cycle Trendly produces a payout run.\n\nThis API is how a merchant's own systems talk to that. You implement against one endpoint: `POST /v1/orders`. Call it whenever an order is placed or changes, and everything downstream (attribution, commission, holds, clawbacks, payout runs, statements, both dashboards) follows from it with no further work on your side.\n\n**Two rules run through the whole API.**\n\n1. *Money is a decimal string.* `\"240.00\"`, never `240.00`. JSON numbers are doubles; 240.10 round-trips as 240.09999999999999, and at volume that becomes a gap between your report and ours that nobody can source.\n2. *Writes are idempotent on your order id.* Retry freely. Replay a whole day. Run a webhook and a nightly reconciliation side by side. The same order can never be counted, or paid, twice.\n\nEvery key is either `trk_test_…` or `trk_live_…`. A test key runs the identical validation, attribution and commission calculation and returns exactly what a live key would have written: then writes nothing. It is not a mock, and there is nothing to clean up afterwards.",
    "contact": {
      "name": "Trendly engineering",
      "url": "https://www.trendly.com.sa/developers"
    }
  },
  "servers": [
    {
      "url": "https://api.trendly.com.sa",
      "description": "Trendly"
    }
  ],
  "security": [
    {
      "bearerAuth": []
    }
  ],
  "tags": [
    {
      "name": "Orders",
      "description": "Reporting sales. The mandatory half of the integration."
    },
    {
      "name": "Codes",
      "description": "Reading the discount codes Trendly has issued, and validating one at checkout."
    },
    {
      "name": "Diagnostics",
      "description": "Confirming a key works, and reading your own call history."
    }
  ],
  "paths": {
    "/v1/ping": {
      "get": {
        "tags": [
          "Diagnostics"
        ],
        "summary": "Verify a key",
        "description": "The first call of any integration. Confirms the key works and says which program and environment it is attached to, along with the three commercial settings every later disagreement turns on: the commission basis, the hold period and the payout cycle.",
        "operationId": "ping",
        "responses": {
          "200": {
            "description": "The key is valid.",
            "content": {
              "application/json": {
                "example": {
                  "ok": true,
                  "environment": "test",
                  "key_name": "Calo checkout",
                  "scopes": [
                    "codes:read",
                    "orders:read",
                    "orders:write",
                    "program:read"
                  ],
                  "program": {
                    "id": "3b0c8f14-0a2e-4c77-9b31-6f5f2a1d4e88",
                    "name": "Calo Market Partners",
                    "currency": "SAR",
                    "status": "active",
                    "commission_basis": "net_ex_vat_ex_shipping",
                    "hold_period_days": 14,
                    "payout_cycle_days": 30
                  },
                  "server_time": "2026-09-18T09:14:22Z"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          }
        }
      }
    },
    "/v1/orders": {
      "post": {
        "tags": [
          "Orders"
        ],
        "summary": "Report one order",
        "description": "Call this when an order is placed, and again whenever it changes: confirmed, cancelled, refunded, partially refunded, flagged.\n\n**Reporting changes is not optional.** An order you report once as `confirmed` and never update is an order we will pay commission on after a refund you knew about. The update call is the same call. We match on `order_id` and reconcile.\n\nThe response tells you what we computed: which creator the code belonged to, what we took the commissionable amount to be, and what it earned. Checking those three numbers at report time is much cheaper than disputing them at payout.",
        "operationId": "reportOrder",
        "parameters": [
          {
            "$ref": "#/components/parameters/IdempotencyKey"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/Order"
              },
              "examples": {
                "minimal": {
                  "summary": "The smallest payload we accept",
                  "value": {
                    "order_id": "ord_01HXYZ",
                    "discount_code": "SARA10",
                    "status": "confirmed",
                    "currency": "SAR",
                    "subtotal_amount": "240.00",
                    "total_amount": "265.65"
                  }
                },
                "complete": {
                  "summary": "Everything we can use",
                  "value": {
                    "order_id": "ord_01HXYZ",
                    "order_number": "CM-10482",
                    "discount_code": "SARA10",
                    "status": "confirmed",
                    "currency": "SAR",
                    "subtotal_amount": "240.00",
                    "discount_amount": "24.00",
                    "shipping_amount": "15.00",
                    "tax_amount": "34.65",
                    "total_amount": "265.65",
                    "refunded_amount": "0.00",
                    "is_new_customer": true,
                    "customer_ref": "cust_8f2a1c",
                    "placed_at": "2026-09-08T11:42:03+03:00",
                    "updated_at": "2026-09-08T11:42:03+03:00",
                    "metadata": {
                      "channel": "app",
                      "branch": "riyadh-01"
                    }
                  }
                },
                "refund": {
                  "summary": "A partial refund on an order reported earlier",
                  "description": "Same order_id. We reverse the proportional share of the commission and, if it was already paid out, carry a clawback into the next cycle.",
                  "value": {
                    "order_id": "ord_01HXYZ",
                    "status": "partially_refunded",
                    "currency": "SAR",
                    "subtotal_amount": "240.00",
                    "discount_amount": "24.00",
                    "shipping_amount": "15.00",
                    "tax_amount": "34.65",
                    "total_amount": "265.65",
                    "refunded_amount": "120.00",
                    "placed_at": "2026-09-08T11:42:03+03:00",
                    "updated_at": "2026-09-14T10:02:00+03:00"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Recorded (live key) or previewed (test key).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/OrderResult"
                },
                "example": {
                  "mode": "live",
                  "recorded": true,
                  "created": true,
                  "updated": false,
                  "order_id": "ord_01HXYZ",
                  "status": "confirmed",
                  "attribution": {
                    "attributed": true,
                    "code": "SARA10",
                    "creator_name": "Sara A.",
                    "membership_id": "9c1e77a2-4b3d-4e91-8f22-11c0a7d5b6e3"
                  },
                  "commission": {
                    "basis_amount": "216.00",
                    "basis": "net_ex_vat_ex_shipping",
                    "rate_type": "percentage",
                    "rate_value": "10.00",
                    "rate_source": "program_default",
                    "amount": "21.60",
                    "currency": "SAR",
                    "capped": false,
                    "payable_after": "2026-09-22T11:42:03Z"
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          }
        }
      }
    },
    "/v1/orders/batch": {
      "post": {
        "tags": [
          "Orders"
        ],
        "summary": "Report up to 500 orders",
        "description": "For backfills and nightly reconciliation. Results are per order. One malformed row does not reject the other 499, and the response says which row to fix. The response is always 200, because the batch itself succeeded.",
        "operationId": "reportOrderBatch",
        "parameters": [
          {
            "$ref": "#/components/parameters/IdempotencyKey"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "orders"
                ],
                "properties": {
                  "orders": {
                    "type": "array",
                    "maxItems": 500,
                    "items": {
                      "$ref": "#/components/schemas/Order"
                    }
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Processed, with a result per order.",
            "content": {
              "application/json": {
                "example": {
                  "mode": "live",
                  "accepted": 2,
                  "rejected": 1,
                  "results": [
                    {
                      "orderId": "ord_1",
                      "status": 200,
                      "result": {
                        "recorded": true,
                        "created": true
                      }
                    },
                    {
                      "orderId": "ord_2",
                      "status": 200,
                      "result": {
                        "recorded": true,
                        "created": false
                      }
                    },
                    {
                      "orderId": "ord_3",
                      "status": 400,
                      "errorCode": "invalid_amount",
                      "message": "'total_amount' is not a decimal amount: SAR 240",
                      "hint": "Send money as a decimal string. Use \"240.00\", not 240.0 and not \"SAR 240\"."
                    }
                  ]
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          }
        }
      }
    },
    "/v1/orders/{orderId}": {
      "get": {
        "tags": [
          "Orders"
        ],
        "summary": "Read an order back",
        "description": "What Trendly holds for one of your orders, including the commission it earned and when that becomes payable. Useful for reconciling your figures against ours before a cycle closes.",
        "operationId": "getOrder",
        "parameters": [
          {
            "name": "orderId",
            "in": "path",
            "required": true,
            "description": "Your own order id, exactly as reported.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The order.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/OrderResult"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          }
        }
      }
    },
    "/v1/codes": {
      "get": {
        "tags": [
          "Codes"
        ],
        "summary": "List discount codes",
        "description": "Every code Trendly has issued for this program, so you can mirror them into your own discount engine.\n\nPoll this with `updated_since` set to your last successful run. Results come back oldest change first, so a code disabled this morning is returned even though it was created months ago.",
        "operationId": "listCodes",
        "parameters": [
          {
            "name": "kind",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "member",
                "gift_single_use",
                "campaign"
              ]
            },
            "description": "`member` is a creator's permanent code. `gift_single_use` is a one-time free-product code. Treat them as separate objects: handling a gift code like a member code is how a free-product code ends up posted to 40,000 followers. Omit for both."
          },
          {
            "name": "updated_since",
            "in": "query",
            "schema": {
              "type": "string",
              "format": "date-time"
            },
            "description": "ISO-8601 with offset. URL-encode the `+` as `%2B`."
          },
          {
            "name": "cursor",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "Pass back `next_cursor` from the previous page, unmodified."
          },
          {
            "name": "limit",
            "in": "query",
            "schema": {
              "type": "integer",
              "default": 100,
              "maximum": 200
            }
          }
        ],
        "responses": {
          "200": {
            "description": "One page of codes.",
            "content": {
              "application/json": {
                "example": {
                  "codes": [
                    {
                      "code": "SARA10",
                      "kind": "member",
                      "status": "active",
                      "discount_type": "percentage",
                      "discount_value": "10.00",
                      "min_order_value": null,
                      "usage_limit": null,
                      "per_customer_limit": 1,
                      "valid_from": "2026-09-10T00:00:00Z",
                      "valid_to": null,
                      "creator_name": "Sara A.",
                      "membership_id": "9c1e77a2-4b3d-4e91-8f22-11c0a7d5b6e3",
                      "updated_at": "2026-09-10T07:31:00Z"
                    }
                  ],
                  "next_cursor": "MTc1NzMyMDkyMzAwMDo5YzFlNzdhMi00YjNkLTRlOTEtOGYyMi0xMWMwYTdkNWI2ZTM",
                  "has_more": true
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          }
        }
      }
    },
    "/v1/codes/{code}": {
      "get": {
        "tags": [
          "Codes"
        ],
        "summary": "Read one code",
        "operationId": "getCode",
        "parameters": [
          {
            "name": "code",
            "in": "path",
            "required": true,
            "description": "Matched case-insensitively.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The code."
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          }
        }
      }
    },
    "/v1/codes/validate": {
      "post": {
        "tags": [
          "Codes"
        ],
        "summary": "Validate a code at checkout",
        "description": "For a checkout that does not hold its own copy of our codes. Send the code and, optionally, the cart total; we answer whether it is usable and what to take off.\n\n**Always returns 200**, including for a bad code. A rejected coupon is a normal checkout outcome, not an error. `valid: false` carries a `reason` to branch on and a `message` to show the shopper.\n\nA key scoped to only `codes:read` is safe to use from a checkout service: it cannot report orders or read your roster.",
        "operationId": "validateCode",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "code"
                ],
                "properties": {
                  "code": {
                    "type": "string",
                    "examples": [
                      "SARA10"
                    ]
                  },
                  "cart_total": {
                    "type": "string",
                    "description": "Decimal string. Omit to skip the minimum-order check and the computed discount.",
                    "examples": [
                      "240.00"
                    ]
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The verdict.",
            "content": {
              "application/json": {
                "examples": {
                  "valid": {
                    "summary": "Usable",
                    "value": {
                      "valid": true,
                      "code": "SARA10",
                      "discount_type": "percentage",
                      "discount_value": "10.00",
                      "discount_amount": "24.00",
                      "creator_name": "Sara A.",
                      "membership_id": "9c1e77a2-4b3d-4e91-8f22-11c0a7d5b6e3"
                    }
                  },
                  "rejected": {
                    "summary": "Not usable",
                    "value": {
                      "valid": false,
                      "code": "SARA99",
                      "reason": "unknown_code",
                      "message": "That code is not part of this program."
                    }
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          }
        }
      }
    },
    "/v1/events": {
      "get": {
        "tags": [
          "Diagnostics"
        ],
        "summary": "Your own call history",
        "description": "Every call made with a key on this program, with the request and response bodies, for the last 30 days. This is the same log the brand sees in their developer portal, reachable with your key. You do not need a Trendly account to debug your own integration.",
        "operationId": "listEvents",
        "parameters": [
          {
            "name": "failures_only",
            "in": "query",
            "schema": {
              "type": "boolean",
              "default": false
            }
          },
          {
            "name": "search",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "Matches an order id, a request id, a path or an error code."
          },
          {
            "name": "limit",
            "in": "query",
            "schema": {
              "type": "integer",
              "default": 25,
              "maximum": 200
            }
          },
          {
            "name": "before",
            "in": "query",
            "schema": {
              "type": "integer"
            },
            "description": "Pass back `next_before` for the previous page."
          }
        ],
        "responses": {
          "200": {
            "description": "Recent calls, newest first."
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          }
        }
      }
    },
    "/v1/events/{requestId}": {
      "get": {
        "tags": [
          "Diagnostics"
        ],
        "summary": "One call in full",
        "description": "By the id returned in the `X-Request-Id` header of every response. Quote it in a support message and we can find the exact call.",
        "operationId": "getEvent",
        "parameters": [
          {
            "name": "requestId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The call."
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          }
        }
      }
    }
  },
  "components": {
    "securitySchemes": {
      "bearerAuth": {
        "type": "http",
        "scheme": "bearer",
        "description": "`Authorization: Bearer trk_live_…`. If your gateway strips the Authorization header, send the same value as `X-API-Key` instead.\n\nKeys are created by the brand in Trendly under Developers, shown once, and stored hashed. We cannot recover a lost key. Rotate it instead."
      }
    },
    "parameters": {
      "IdempotencyKey": {
        "name": "Idempotency-Key",
        "in": "header",
        "required": false,
        "schema": {
          "type": "string",
          "maxLength": 128
        },
        "description": "Optional. A unique value, ideally a UUID, that makes a replay return the original response rather than a fresh one. Writes are already idempotent on `order_id`, so this is for your retry logic rather than the ledger. Reusing a key with a different body returns 409."
      }
    },
    "responses": {
      "BadRequest": {
        "description": "The payload could not be used. Permanent: fix it and resend rather than retrying.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            },
            "example": {
              "error": {
                "code": "invalid_amount",
                "message": "'total_amount' is not a decimal amount: 265.65000000000003",
                "field": "total_amount",
                "hint": "Send money as a decimal string. Use \"240.00\", not 240.0 and not \"SAR 240\". JSON numbers are doubles and lose halalas at volume.",
                "documentation_url": "https://www.trendly.com.sa/developers#orders"
              },
              "request_id": "8f14d2a1-7c3b-4e55-9a20-3d6b1f0c9e47"
            }
          }
        }
      },
      "Unauthorized": {
        "description": "The key is missing, malformed, revoked or expired. The body says which.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            }
          }
        }
      },
      "Forbidden": {
        "description": "The key is valid but lacks the scope this endpoint needs.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            }
          }
        }
      },
      "NotFound": {
        "description": "No such object in this program.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            }
          }
        }
      },
      "Conflict": {
        "description": "An idempotency key was reused with a different body.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            }
          }
        }
      }
    },
    "schemas": {
      "Money": {
        "type": "string",
        "pattern": "^-?[0-9]{1,10}(\\.[0-9]{1,2})?$",
        "description": "A decimal string. Two decimal places, ten digits before them. Never a JSON number.",
        "examples": [
          "240.00",
          "0.00"
        ]
      },
      "Order": {
        "type": "object",
        "required": [
          "order_id",
          "status",
          "subtotal_amount",
          "total_amount"
        ],
        "properties": {
          "order_id": {
            "type": "string",
            "description": "Your permanent order identifier. Never reused. This is the idempotency key for the ledger: report the same order twice and it converges on one row."
          },
          "order_number": {
            "type": "string",
            "description": "Human-readable reference for support."
          },
          "discount_code": {
            "type": "string",
            "description": "The code as applied. Matched case-insensitively. An order carrying a code we do not know is still recorded, in an unattributed queue the brand can see."
          },
          "status": {
            "$ref": "#/components/schemas/OrderStatus"
          },
          "currency": {
            "type": "string",
            "description": "ISO-4217. Defaults to the program's currency. An order in another currency returns 400 rather than being converted at a rate nobody agreed.",
            "examples": [
              "SAR"
            ]
          },
          "subtotal_amount": {
            "$ref": "#/components/schemas/Money",
            "description": "Goods value before discount, excluding VAT and shipping."
          },
          "discount_amount": {
            "$ref": "#/components/schemas/Money",
            "description": "Discount applied by this code."
          },
          "shipping_amount": {
            "$ref": "#/components/schemas/Money"
          },
          "tax_amount": {
            "$ref": "#/components/schemas/Money",
            "description": "VAT charged."
          },
          "total_amount": {
            "$ref": "#/components/schemas/Money",
            "description": "What the customer actually paid."
          },
          "refunded_amount": {
            "$ref": "#/components/schemas/Money",
            "description": "Cumulative refunded to date. Required once a refund has happened."
          },
          "commissionable_amount": {
            "$ref": "#/components/schemas/Money",
            "description": "Your own commission basis. Only read when the program is configured as `merchant_declared`, and only safe when you have documented how you compute it."
          },
          "is_new_customer": {
            "type": "boolean"
          },
          "customer_ref": {
            "type": "string",
            "description": "**Pseudonymous only.** A hash or internal id, stable per customer and meaningless outside your system. Used for the new vs returning split and self-purchase detection, and nothing else. We reject anything that looks like an email or a phone number."
          },
          "placed_at": {
            "type": "string",
            "format": "date-time",
            "description": "ISO-8601 with offset. Required for backfills. Without it we use the time of the call."
          },
          "updated_at": {
            "type": "string",
            "format": "date-time"
          },
          "status_changed_at": {
            "type": "string",
            "format": "date-time"
          },
          "metadata": {
            "type": "object",
            "additionalProperties": true,
            "description": "Stored with the order and never parsed. Put whatever helps you reconcile."
          }
        }
      },
      "OrderStatus": {
        "type": "string",
        "enum": [
          "pending",
          "confirmed",
          "cancelled",
          "refunded",
          "partially_refunded",
          "fraud"
        ],
        "description": "Map your own vocabulary onto these, and tell us the mapping.\n\n| Status | Commission effect |\n|---|---|\n| `pending` | Nothing accrues |\n| `confirmed` | Accrues, held until the hold period elapses |\n| `cancelled` | Reversed |\n| `refunded` | Reversed in full |\n| `partially_refunded` | Reversed proportionally |\n| `fraud` | Reversed, and the creator is flagged for review |\n\nAn unmapped status is a silent failure: orders stop accruing and nobody notices until a creator asks why their earnings stalled. We return 400 rather than guessing."
      },
      "OrderResult": {
        "type": "object",
        "properties": {
          "mode": {
            "type": "string",
            "enum": [
              "live",
              "test"
            ]
          },
          "recorded": {
            "type": "boolean",
            "description": "False only when a call was rejected."
          },
          "created": {
            "type": "boolean"
          },
          "updated": {
            "type": "boolean"
          },
          "order_id": {
            "type": "string"
          },
          "status": {
            "$ref": "#/components/schemas/OrderStatus"
          },
          "attribution": {
            "type": "object",
            "properties": {
              "attributed": {
                "type": "boolean"
              },
              "code": {
                "type": "string"
              },
              "creator_name": {
                "type": "string"
              },
              "membership_id": {
                "type": "string"
              },
              "campaign_id": {
                "type": "string"
              },
              "note": {
                "type": "string",
                "description": "Why the code matched nobody, when it did not."
              }
            }
          },
          "commission": {
            "type": "object",
            "properties": {
              "basis_amount": {
                "$ref": "#/components/schemas/Money"
              },
              "basis": {
                "type": "string",
                "enum": [
                  "gross",
                  "net_ex_vat",
                  "net_ex_vat_ex_shipping",
                  "merchant_declared"
                ]
              },
              "rate_type": {
                "type": "string",
                "enum": [
                  "percentage",
                  "fixed"
                ]
              },
              "rate_value": {
                "type": "string"
              },
              "rate_source": {
                "type": "string",
                "description": "Which link in the rate chain won: a campaign, a membership override, a tier, or the program default."
              },
              "amount": {
                "$ref": "#/components/schemas/Money"
              },
              "currency": {
                "type": "string"
              },
              "capped": {
                "type": "boolean",
                "description": "A campaign cap clipped the amount."
              },
              "payable_after": {
                "type": "string",
                "format": "date-time",
                "description": "When the hold period elapses and the money becomes payable."
              },
              "note": {
                "type": "string"
              }
            }
          },
          "warnings": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Accepted, but worth fixing: amounts that do not balance, a timestamp with no offset, a status that does not accrue. Never a reason to retry."
          }
        }
      },
      "Error": {
        "type": "object",
        "properties": {
          "error": {
            "type": "object",
            "properties": {
              "code": {
                "type": "string",
                "description": "Stable and machine-readable. Branch on this, not on the message."
              },
              "message": {
                "type": "string"
              },
              "field": {
                "type": "string",
                "description": "Which part of your payload is wrong."
              },
              "hint": {
                "type": "string",
                "description": "What to do about it."
              },
              "documentation_url": {
                "type": "string"
              }
            }
          },
          "request_id": {
            "type": "string",
            "description": "Also in the `X-Request-Id` header. Quote it and we can find this exact call."
          }
        }
      }
    }
  }
}
