{
  "openapi": "3.1.0",
  "paths": {
    "/v1/status": {
      "get": {
        "description": "Public status of Flashpi. Placeholder: it reports `operational` while the API answers; component and SRI availability arrive with the status page.",
        "operationId": "statusGet",
        "parameters": [
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          },
          {
            "$ref": "#/components/parameters/CorrelationId"
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Status"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/RequestId"
              }
            }
          }
        },
        "summary": "Service status",
        "tags": [
          "Status"
        ]
      }
    },
    "/v1/issuers": {
      "post": {
        "description": "Registers a taxpayer (RUC) with its tax profile. Requires an account-scoped (global) API key with read_write access.",
        "operationId": "issuersCreate",
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "description": "Makes the request safe to retry: 1 to 255 visible ASCII characters (a UUID works well), remembered for 24 hours per account and mode. A retry with the same key and the same request returns the first successful response again, with the header `Idempotent-Replayed: true`. The same key with a different request gets 422 idempotency_key_reused; while the first request still runs, 409 idempotency_key_in_progress. A failed request does not keep its key.",
            "schema": {
              "type": "string",
              "minLength": 1,
              "maxLength": 255,
              "pattern": "^[\\x21-\\x7E]+$"
            }
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          },
          {
            "$ref": "#/components/parameters/CorrelationId"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateIssuer"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Issuer"
                }
              }
            },
            "headers": {
              "Idempotent-Replayed": {
                "required": false,
                "description": "`true` when this is the stored answer of an earlier request with the same Idempotency-Key (same status and body, no Location). Absent otherwise.",
                "schema": {
                  "type": "string",
                  "enum": [
                    "true"
                  ]
                }
              },
              "X-Request-Id": {
                "$ref": "#/components/headers/RequestId"
              }
            }
          },
          "400": {
            "description": "`malformed_json`: the body is not valid JSON. `bad_request`: the body does not decompress with its `Content-Encoding`. Or invalid_idempotency_key: the Idempotency-Key header is malformed.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "`authentication_required`: no `Authorization: Bearer` header. `invalid_api_key`: the key is malformed, unknown or revoked.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            },
            "headers": {
              "WWW-Authenticate": {
                "$ref": "#/components/headers/WwwAuthenticate"
              }
            }
          },
          "403": {
            "description": "The API key cannot perform this operation: key_scope_mismatch, key_read_only or ip_not_allowed; or its account is suspended (account_suspended).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "409": {
            "description": "issuer_already_exists: the account already has an issuer with this RUC. Or idempotency_key_in_progress: a request with this Idempotency-Key is still running.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "413": {
            "description": "`payload_too_large`: the JSON body is larger than 1 MB.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "415": {
            "description": "`unsupported_media_type`: the body declares a charset that does not start with `utf-` (for example `latin1`, or `utf8` without the hyphen) or a `Content-Encoding` other than gzip, deflate or br.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "422": {
            "description": "validation_failed: see errors. Or idempotency_key_reused: the Idempotency-Key was used with a different request.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "apiKey": []
          }
        ],
        "summary": "Create an issuer",
        "tags": [
          "Issuers"
        ]
      },
      "get": {
        "description": "Newest first. Requires an account-scoped (global) API key with read_write access.",
        "operationId": "issuersList",
        "parameters": [
          {
            "name": "limit",
            "required": false,
            "in": "query",
            "description": "Maximum number of items to return.",
            "schema": {
              "minimum": 1,
              "maximum": 100,
              "default": 20,
              "type": "integer"
            }
          },
          {
            "name": "cursor",
            "required": false,
            "in": "query",
            "description": "The `pagination.nextCursor` of the previous page. Omit it for the first page.",
            "schema": {
              "maxLength": 200,
              "type": "string"
            }
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          },
          {
            "$ref": "#/components/parameters/CorrelationId"
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/IssuerList"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/RequestId"
              }
            }
          },
          "401": {
            "description": "`authentication_required`: no `Authorization: Bearer` header. `invalid_api_key`: the key is malformed, unknown or revoked.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            },
            "headers": {
              "WWW-Authenticate": {
                "$ref": "#/components/headers/WwwAuthenticate"
              }
            }
          },
          "403": {
            "description": "The API key cannot perform this operation: key_scope_mismatch, key_read_only or ip_not_allowed; or its account is suspended (account_suspended).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "422": {
            "description": "validation_failed: invalid limit or cursor.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "apiKey": []
          }
        ],
        "summary": "List issuers",
        "tags": [
          "Issuers"
        ]
      }
    },
    "/v1/issuers/{issuerId}": {
      "get": {
        "description": "Requires an account-scoped (global) API key with read_write access.",
        "operationId": "issuersGet",
        "parameters": [
          {
            "name": "issuerId",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          },
          {
            "$ref": "#/components/parameters/CorrelationId"
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Issuer"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/RequestId"
              }
            }
          },
          "401": {
            "description": "`authentication_required`: no `Authorization: Bearer` header. `invalid_api_key`: the key is malformed, unknown or revoked.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            },
            "headers": {
              "WWW-Authenticate": {
                "$ref": "#/components/headers/WwwAuthenticate"
              }
            }
          },
          "403": {
            "description": "The API key cannot perform this operation: key_scope_mismatch, key_read_only or ip_not_allowed; or its account is suspended (account_suspended).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "not_found",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "apiKey": []
          }
        ],
        "summary": "Get an issuer",
        "tags": [
          "Issuers"
        ]
      },
      "patch": {
        "description": "Changes the fields sent; null clears an optional field. The RUC cannot change. Requires an account-scoped (global) API key with read_write access.",
        "operationId": "issuersUpdate",
        "parameters": [
          {
            "name": "issuerId",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          },
          {
            "$ref": "#/components/parameters/CorrelationId"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/UpdateIssuer"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Issuer"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/RequestId"
              }
            }
          },
          "400": {
            "description": "`malformed_json`: the body is not valid JSON. `bad_request`: the body does not decompress with its `Content-Encoding`.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "`authentication_required`: no `Authorization: Bearer` header. `invalid_api_key`: the key is malformed, unknown or revoked.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            },
            "headers": {
              "WWW-Authenticate": {
                "$ref": "#/components/headers/WwwAuthenticate"
              }
            }
          },
          "403": {
            "description": "The API key cannot perform this operation: key_scope_mismatch, key_read_only or ip_not_allowed; or its account is suspended (account_suspended).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "not_found",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "413": {
            "description": "`payload_too_large`: the JSON body is larger than 1 MB.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "415": {
            "description": "`unsupported_media_type`: the body declares a charset that does not start with `utf-` (for example `latin1`, or `utf8` without the hyphen) or a `Content-Encoding` other than gzip, deflate or br.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "422": {
            "description": "validation_failed: see errors.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "apiKey": []
          }
        ],
        "summary": "Update an issuer",
        "tags": [
          "Issuers"
        ]
      },
      "delete": {
        "description": "Deletes the issuer with its establishments, emission points and issuer-scoped API keys. An issuer with documents or certificates cannot be deleted. Requires an account-scoped (global) API key with read_write access.",
        "operationId": "issuersDelete",
        "parameters": [
          {
            "name": "issuerId",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          },
          {
            "$ref": "#/components/parameters/CorrelationId"
          }
        ],
        "responses": {
          "204": {
            "description": "Deleted.",
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/RequestId"
              }
            }
          },
          "401": {
            "description": "`authentication_required`: no `Authorization: Bearer` header. `invalid_api_key`: the key is malformed, unknown or revoked.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            },
            "headers": {
              "WWW-Authenticate": {
                "$ref": "#/components/headers/WwwAuthenticate"
              }
            }
          },
          "403": {
            "description": "The API key cannot perform this operation: key_scope_mismatch, key_read_only or ip_not_allowed; or its account is suspended (account_suspended).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "not_found",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "409": {
            "description": "resource_in_use: the issuer has documents or certificates.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "apiKey": []
          }
        ],
        "summary": "Delete an issuer",
        "tags": [
          "Issuers"
        ]
      }
    },
    "/v1/issuers/{issuerId}/establishments": {
      "post": {
        "description": "Requires an account-scoped (global) API key with read_write access.",
        "operationId": "establishmentsCreate",
        "parameters": [
          {
            "name": "issuerId",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "description": "Makes the request safe to retry: 1 to 255 visible ASCII characters (a UUID works well), remembered for 24 hours per account and mode. A retry with the same key and the same request returns the first successful response again, with the header `Idempotent-Replayed: true`. The same key with a different request gets 422 idempotency_key_reused; while the first request still runs, 409 idempotency_key_in_progress. A failed request does not keep its key.",
            "schema": {
              "type": "string",
              "minLength": 1,
              "maxLength": 255,
              "pattern": "^[\\x21-\\x7E]+$"
            }
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          },
          {
            "$ref": "#/components/parameters/CorrelationId"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateEstablishment"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Establishment"
                }
              }
            },
            "headers": {
              "Idempotent-Replayed": {
                "required": false,
                "description": "`true` when this is the stored answer of an earlier request with the same Idempotency-Key (same status and body, no Location). Absent otherwise.",
                "schema": {
                  "type": "string",
                  "enum": [
                    "true"
                  ]
                }
              },
              "X-Request-Id": {
                "$ref": "#/components/headers/RequestId"
              }
            }
          },
          "400": {
            "description": "`malformed_json`: the body is not valid JSON. `bad_request`: the body does not decompress with its `Content-Encoding`. Or invalid_idempotency_key: the Idempotency-Key header is malformed.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "`authentication_required`: no `Authorization: Bearer` header. `invalid_api_key`: the key is malformed, unknown or revoked.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            },
            "headers": {
              "WWW-Authenticate": {
                "$ref": "#/components/headers/WwwAuthenticate"
              }
            }
          },
          "403": {
            "description": "The API key cannot perform this operation: key_scope_mismatch, key_read_only or ip_not_allowed; or its account is suspended (account_suspended).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "not_found: no such issuer.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "409": {
            "description": "establishment_already_exists: the issuer already has this code. Or idempotency_key_in_progress: a request with this Idempotency-Key is still running.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "413": {
            "description": "`payload_too_large`: the JSON body is larger than 1 MB.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "415": {
            "description": "`unsupported_media_type`: the body declares a charset that does not start with `utf-` (for example `latin1`, or `utf8` without the hyphen) or a `Content-Encoding` other than gzip, deflate or br.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "422": {
            "description": "validation_failed: see errors. Or idempotency_key_reused: the Idempotency-Key was used with a different request.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "apiKey": []
          }
        ],
        "summary": "Create an establishment",
        "tags": [
          "Issuers"
        ]
      },
      "get": {
        "description": "By code. Requires an account-scoped (global) API key with read_write access.",
        "operationId": "establishmentsList",
        "parameters": [
          {
            "name": "issuerId",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "limit",
            "required": false,
            "in": "query",
            "description": "Maximum number of items to return.",
            "schema": {
              "minimum": 1,
              "maximum": 100,
              "default": 20,
              "type": "integer"
            }
          },
          {
            "name": "cursor",
            "required": false,
            "in": "query",
            "description": "The `pagination.nextCursor` of the previous page. Omit it for the first page.",
            "schema": {
              "maxLength": 200,
              "type": "string"
            }
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          },
          {
            "$ref": "#/components/parameters/CorrelationId"
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/EstablishmentList"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/RequestId"
              }
            }
          },
          "401": {
            "description": "`authentication_required`: no `Authorization: Bearer` header. `invalid_api_key`: the key is malformed, unknown or revoked.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            },
            "headers": {
              "WWW-Authenticate": {
                "$ref": "#/components/headers/WwwAuthenticate"
              }
            }
          },
          "403": {
            "description": "The API key cannot perform this operation: key_scope_mismatch, key_read_only or ip_not_allowed; or its account is suspended (account_suspended).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "not_found: no such issuer.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "422": {
            "description": "validation_failed: invalid limit or cursor.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "apiKey": []
          }
        ],
        "summary": "List establishments",
        "tags": [
          "Issuers"
        ]
      }
    },
    "/v1/issuers/{issuerId}/establishments/{establishmentId}": {
      "get": {
        "description": "Requires an account-scoped (global) API key with read_write access.",
        "operationId": "establishmentsGet",
        "parameters": [
          {
            "name": "issuerId",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "establishmentId",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          },
          {
            "$ref": "#/components/parameters/CorrelationId"
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Establishment"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/RequestId"
              }
            }
          },
          "401": {
            "description": "`authentication_required`: no `Authorization: Bearer` header. `invalid_api_key`: the key is malformed, unknown or revoked.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            },
            "headers": {
              "WWW-Authenticate": {
                "$ref": "#/components/headers/WwwAuthenticate"
              }
            }
          },
          "403": {
            "description": "The API key cannot perform this operation: key_scope_mismatch, key_read_only or ip_not_allowed; or its account is suspended (account_suspended).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "not_found",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "apiKey": []
          }
        ],
        "summary": "Get an establishment",
        "tags": [
          "Issuers"
        ]
      },
      "patch": {
        "description": "Changes the address. The code cannot change. Requires an account-scoped (global) API key with read_write access.",
        "operationId": "establishmentsUpdate",
        "parameters": [
          {
            "name": "issuerId",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "establishmentId",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          },
          {
            "$ref": "#/components/parameters/CorrelationId"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/UpdateEstablishment"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Establishment"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/RequestId"
              }
            }
          },
          "400": {
            "description": "`malformed_json`: the body is not valid JSON. `bad_request`: the body does not decompress with its `Content-Encoding`.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "`authentication_required`: no `Authorization: Bearer` header. `invalid_api_key`: the key is malformed, unknown or revoked.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            },
            "headers": {
              "WWW-Authenticate": {
                "$ref": "#/components/headers/WwwAuthenticate"
              }
            }
          },
          "403": {
            "description": "The API key cannot perform this operation: key_scope_mismatch, key_read_only or ip_not_allowed; or its account is suspended (account_suspended).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "not_found",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "413": {
            "description": "`payload_too_large`: the JSON body is larger than 1 MB.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "415": {
            "description": "`unsupported_media_type`: the body declares a charset that does not start with `utf-` (for example `latin1`, or `utf8` without the hyphen) or a `Content-Encoding` other than gzip, deflate or br.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "422": {
            "description": "validation_failed: see errors.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "apiKey": []
          }
        ],
        "summary": "Update an establishment",
        "tags": [
          "Issuers"
        ]
      },
      "delete": {
        "description": "Deletes it with its emission points; refused when documents use it. Requires an account-scoped (global) API key with read_write access.",
        "operationId": "establishmentsDelete",
        "parameters": [
          {
            "name": "issuerId",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "establishmentId",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          },
          {
            "$ref": "#/components/parameters/CorrelationId"
          }
        ],
        "responses": {
          "204": {
            "description": "Deleted.",
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/RequestId"
              }
            }
          },
          "401": {
            "description": "`authentication_required`: no `Authorization: Bearer` header. `invalid_api_key`: the key is malformed, unknown or revoked.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            },
            "headers": {
              "WWW-Authenticate": {
                "$ref": "#/components/headers/WwwAuthenticate"
              }
            }
          },
          "403": {
            "description": "The API key cannot perform this operation: key_scope_mismatch, key_read_only or ip_not_allowed; or its account is suspended (account_suspended).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "not_found",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "409": {
            "description": "resource_in_use: documents use the establishment.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "apiKey": []
          }
        ],
        "summary": "Delete an establishment",
        "tags": [
          "Issuers"
        ]
      }
    },
    "/v1/issuers/{issuerId}/establishments/{establishmentId}/emission-points": {
      "post": {
        "description": "Requires an account-scoped (global) API key with read_write access.",
        "operationId": "emissionPointsCreate",
        "parameters": [
          {
            "name": "issuerId",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "establishmentId",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "description": "Makes the request safe to retry: 1 to 255 visible ASCII characters (a UUID works well), remembered for 24 hours per account and mode. A retry with the same key and the same request returns the first successful response again, with the header `Idempotent-Replayed: true`. The same key with a different request gets 422 idempotency_key_reused; while the first request still runs, 409 idempotency_key_in_progress. A failed request does not keep its key.",
            "schema": {
              "type": "string",
              "minLength": 1,
              "maxLength": 255,
              "pattern": "^[\\x21-\\x7E]+$"
            }
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          },
          {
            "$ref": "#/components/parameters/CorrelationId"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateEmissionPoint"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/EmissionPoint"
                }
              }
            },
            "headers": {
              "Idempotent-Replayed": {
                "required": false,
                "description": "`true` when this is the stored answer of an earlier request with the same Idempotency-Key (same status and body, no Location). Absent otherwise.",
                "schema": {
                  "type": "string",
                  "enum": [
                    "true"
                  ]
                }
              },
              "X-Request-Id": {
                "$ref": "#/components/headers/RequestId"
              }
            }
          },
          "400": {
            "description": "`malformed_json`: the body is not valid JSON. `bad_request`: the body does not decompress with its `Content-Encoding`. Or invalid_idempotency_key: the Idempotency-Key header is malformed.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "`authentication_required`: no `Authorization: Bearer` header. `invalid_api_key`: the key is malformed, unknown or revoked.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            },
            "headers": {
              "WWW-Authenticate": {
                "$ref": "#/components/headers/WwwAuthenticate"
              }
            }
          },
          "403": {
            "description": "The API key cannot perform this operation: key_scope_mismatch, key_read_only or ip_not_allowed; or its account is suspended (account_suspended).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "not_found: no such issuer or establishment.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "409": {
            "description": "emission_point_already_exists: the establishment already has this code. Or idempotency_key_in_progress: a request with this Idempotency-Key is still running.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "413": {
            "description": "`payload_too_large`: the JSON body is larger than 1 MB.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "415": {
            "description": "`unsupported_media_type`: the body declares a charset that does not start with `utf-` (for example `latin1`, or `utf8` without the hyphen) or a `Content-Encoding` other than gzip, deflate or br.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "422": {
            "description": "validation_failed: see errors. Or idempotency_key_reused: the Idempotency-Key was used with a different request.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "apiKey": []
          }
        ],
        "summary": "Create an emission point",
        "tags": [
          "Issuers"
        ]
      },
      "get": {
        "description": "By code. Requires an account-scoped (global) API key with read_write access.",
        "operationId": "emissionPointsList",
        "parameters": [
          {
            "name": "issuerId",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "establishmentId",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "limit",
            "required": false,
            "in": "query",
            "description": "Maximum number of items to return.",
            "schema": {
              "minimum": 1,
              "maximum": 100,
              "default": 20,
              "type": "integer"
            }
          },
          {
            "name": "cursor",
            "required": false,
            "in": "query",
            "description": "The `pagination.nextCursor` of the previous page. Omit it for the first page.",
            "schema": {
              "maxLength": 200,
              "type": "string"
            }
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          },
          {
            "$ref": "#/components/parameters/CorrelationId"
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/EmissionPointList"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/RequestId"
              }
            }
          },
          "401": {
            "description": "`authentication_required`: no `Authorization: Bearer` header. `invalid_api_key`: the key is malformed, unknown or revoked.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            },
            "headers": {
              "WWW-Authenticate": {
                "$ref": "#/components/headers/WwwAuthenticate"
              }
            }
          },
          "403": {
            "description": "The API key cannot perform this operation: key_scope_mismatch, key_read_only or ip_not_allowed; or its account is suspended (account_suspended).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "not_found: no such issuer or establishment.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "422": {
            "description": "validation_failed: invalid limit or cursor.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "apiKey": []
          }
        ],
        "summary": "List emission points",
        "tags": [
          "Issuers"
        ]
      }
    },
    "/v1/issuers/{issuerId}/establishments/{establishmentId}/emission-points/{emissionPointId}": {
      "get": {
        "description": "Requires an account-scoped (global) API key with read_write access.",
        "operationId": "emissionPointsGet",
        "parameters": [
          {
            "name": "issuerId",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "establishmentId",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "emissionPointId",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          },
          {
            "$ref": "#/components/parameters/CorrelationId"
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/EmissionPoint"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/RequestId"
              }
            }
          },
          "401": {
            "description": "`authentication_required`: no `Authorization: Bearer` header. `invalid_api_key`: the key is malformed, unknown or revoked.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            },
            "headers": {
              "WWW-Authenticate": {
                "$ref": "#/components/headers/WwwAuthenticate"
              }
            }
          },
          "403": {
            "description": "The API key cannot perform this operation: key_scope_mismatch, key_read_only or ip_not_allowed; or its account is suspended (account_suspended).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "not_found",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "apiKey": []
          }
        ],
        "summary": "Get an emission point",
        "tags": [
          "Issuers"
        ]
      },
      "delete": {
        "description": "Refused when documents use it. Requires an account-scoped (global) API key with read_write access.",
        "operationId": "emissionPointsDelete",
        "parameters": [
          {
            "name": "issuerId",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "establishmentId",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "emissionPointId",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          },
          {
            "$ref": "#/components/parameters/CorrelationId"
          }
        ],
        "responses": {
          "204": {
            "description": "Deleted.",
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/RequestId"
              }
            }
          },
          "401": {
            "description": "`authentication_required`: no `Authorization: Bearer` header. `invalid_api_key`: the key is malformed, unknown or revoked.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            },
            "headers": {
              "WWW-Authenticate": {
                "$ref": "#/components/headers/WwwAuthenticate"
              }
            }
          },
          "403": {
            "description": "The API key cannot perform this operation: key_scope_mismatch, key_read_only or ip_not_allowed; or its account is suspended (account_suspended).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "not_found",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "409": {
            "description": "resource_in_use: documents use the emission point.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "apiKey": []
          }
        ],
        "summary": "Delete an emission point",
        "tags": [
          "Issuers"
        ]
      }
    },
    "/v1/issuers/{issuerId}/certificates": {
      "post": {
        "description": "Uploads the .p12 (PKCS#12) file and its password as multipart/form-data. Flashpi encrypts both at once and checks them asynchronously (password, signing key, validity, trusted Ecuadorian certification authority, revocation): the certificate starts `processing`, then becomes `accepted` or `rejected`; follow it with GET. The password is never stored in clear nor returned. Requires an account-scoped (global) API key with read_write access. Test keys manage test certificates and live keys live ones; a certificate of the issuer onboarding serves both modes (`allModes`) and both read it.",
        "operationId": "certificatesUpload",
        "parameters": [
          {
            "name": "issuerId",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "description": "Makes the request safe to retry: 1 to 255 visible ASCII characters (a UUID works well), remembered for 24 hours per account and mode. A retry with the same key and the same request returns the first successful response again, with the header `Idempotent-Replayed: true`. The same key with a different request gets 422 idempotency_key_reused; while the first request still runs, 409 idempotency_key_in_progress. A failed request does not keep its key.",
            "schema": {
              "type": "string",
              "minLength": 1,
              "maxLength": 255,
              "pattern": "^[\\x21-\\x7E]+$"
            }
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          },
          {
            "$ref": "#/components/parameters/CorrelationId"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "multipart/form-data": {
              "schema": {
                "type": "object",
                "required": [
                  "file",
                  "password"
                ],
                "properties": {
                  "file": {
                    "type": "string",
                    "format": "binary",
                    "description": "The .p12 file, at most 1048576 bytes."
                  },
                  "password": {
                    "type": "string",
                    "format": "password",
                    "description": "Its password, at most 1024 bytes in UTF-8."
                  }
                }
              }
            }
          }
        },
        "responses": {
          "202": {
            "description": "Accepted for checking: status `processing`.",
            "headers": {
              "Location": {
                "description": "Path of the certificate: /v1/issuers/{issuerId}/certificates/{id}. Not sent on an idempotent replay (Idempotent-Replayed: true): build it from the body as shown.",
                "schema": {
                  "type": "string"
                },
                "required": false
              },
              "Idempotent-Replayed": {
                "required": false,
                "description": "`true` when this is the stored answer of an earlier request with the same Idempotency-Key (same status and body, no Location). Absent otherwise.",
                "schema": {
                  "type": "string",
                  "enum": [
                    "true"
                  ]
                }
              },
              "X-Request-Id": {
                "$ref": "#/components/headers/RequestId"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Certificate"
                }
              }
            }
          },
          "400": {
            "description": "invalid_idempotency_key: the Idempotency-Key header is malformed.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "`authentication_required`: no `Authorization: Bearer` header. `invalid_api_key`: the key is malformed, unknown or revoked.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            },
            "headers": {
              "WWW-Authenticate": {
                "$ref": "#/components/headers/WwwAuthenticate"
              }
            }
          },
          "403": {
            "description": "The API key cannot perform this operation: key_scope_mismatch, key_read_only or ip_not_allowed; or its account is suspended (account_suspended).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "not_found: the issuer does not exist.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "409": {
            "description": "idempotency_key_in_progress: a request with this Idempotency-Key is still running.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "413": {
            "description": "payload_too_large: the file is larger than 1 MiB.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "422": {
            "description": "validation_failed: the file or the password is missing or too long. Or idempotency_key_reused: the Idempotency-Key was used with a different request.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "apiKey": []
          }
        ],
        "summary": "Upload an issuer's signing certificate",
        "tags": [
          "Certificates"
        ]
      },
      "get": {
        "description": "Newest first. Requires an account-scoped (global) API key with read_write access. Test keys manage test certificates and live keys live ones; a certificate of the issuer onboarding serves both modes (`allModes`) and both read it.",
        "operationId": "certificatesList",
        "parameters": [
          {
            "name": "issuerId",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "limit",
            "required": false,
            "in": "query",
            "description": "Maximum number of items to return.",
            "schema": {
              "minimum": 1,
              "maximum": 100,
              "default": 20,
              "type": "integer"
            }
          },
          {
            "name": "cursor",
            "required": false,
            "in": "query",
            "description": "The `pagination.nextCursor` of the previous page. Omit it for the first page.",
            "schema": {
              "maxLength": 200,
              "type": "string"
            }
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          },
          {
            "$ref": "#/components/parameters/CorrelationId"
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CertificateList"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/RequestId"
              }
            }
          },
          "401": {
            "description": "`authentication_required`: no `Authorization: Bearer` header. `invalid_api_key`: the key is malformed, unknown or revoked.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            },
            "headers": {
              "WWW-Authenticate": {
                "$ref": "#/components/headers/WwwAuthenticate"
              }
            }
          },
          "403": {
            "description": "The API key cannot perform this operation: key_scope_mismatch, key_read_only or ip_not_allowed; or its account is suspended (account_suspended).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "not_found",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "422": {
            "description": "validation_failed: invalid limit or cursor.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "apiKey": []
          }
        ],
        "summary": "List an issuer's certificates",
        "tags": [
          "Certificates"
        ]
      }
    },
    "/v1/issuers/{issuerId}/certificates/{certificateId}": {
      "get": {
        "description": "Requires an account-scoped (global) API key with read_write access. Test keys manage test certificates and live keys live ones; a certificate of the issuer onboarding serves both modes (`allModes`) and both read it.",
        "operationId": "certificatesGet",
        "parameters": [
          {
            "name": "issuerId",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "certificateId",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          },
          {
            "$ref": "#/components/parameters/CorrelationId"
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Certificate"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/RequestId"
              }
            }
          },
          "401": {
            "description": "`authentication_required`: no `Authorization: Bearer` header. `invalid_api_key`: the key is malformed, unknown or revoked.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            },
            "headers": {
              "WWW-Authenticate": {
                "$ref": "#/components/headers/WwwAuthenticate"
              }
            }
          },
          "403": {
            "description": "The API key cannot perform this operation: key_scope_mismatch, key_read_only or ip_not_allowed; or its account is suspended (account_suspended).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "not_found",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "apiKey": []
          }
        ],
        "summary": "Get a certificate",
        "tags": [
          "Certificates"
        ]
      }
    },
    "/v1/issuer-onboardings": {
      "post": {
        "description": "Uploads the .p12 (PKCS#12) file and its password as multipart/form-data. Flashpi encrypts both at once and verifies them asynchronously (password, signing key, validity, trusted Ecuadorian certification authority, revocation): the onboarding starts `verifying`; retrieve it until it is `ready` (with the RUC and the holder, plus the SRI's profile when the registry lookup is on: see `sri.status`) or `rejected`, then complete it within 6 days. The password is never stored in clear nor returned. Requires an account-scoped (global) API key with read_write access, of either mode: the certificate serves test and live documents.",
        "operationId": "issuerOnboardingsCreate",
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "description": "Makes the request safe to retry: 1 to 255 visible ASCII characters (a UUID works well), remembered for 24 hours per account and mode. A retry with the same key and the same request returns the first successful response again, with the header `Idempotent-Replayed: true`. The same key with a different request gets 422 idempotency_key_reused; while the first request still runs, 409 idempotency_key_in_progress. A failed request does not keep its key.",
            "schema": {
              "type": "string",
              "minLength": 1,
              "maxLength": 255,
              "pattern": "^[\\x21-\\x7E]+$"
            }
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          },
          {
            "$ref": "#/components/parameters/CorrelationId"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "multipart/form-data": {
              "schema": {
                "type": "object",
                "required": [
                  "file",
                  "password"
                ],
                "properties": {
                  "file": {
                    "type": "string",
                    "format": "binary",
                    "description": "The .p12 file, at most 1048576 bytes."
                  },
                  "password": {
                    "type": "string",
                    "format": "password",
                    "description": "Its password, at most 1024 bytes in UTF-8."
                  }
                }
              }
            }
          }
        },
        "responses": {
          "202": {
            "description": "Accepted for verification: status `verifying`.",
            "headers": {
              "Location": {
                "description": "Path of the onboarding: /v1/issuer-onboardings/{id}. Not sent on an idempotent replay (Idempotent-Replayed: true): build it from the body as shown.",
                "schema": {
                  "type": "string"
                },
                "required": false
              },
              "Idempotent-Replayed": {
                "required": false,
                "description": "`true` when this is the stored answer of an earlier request with the same Idempotency-Key (same status and body, no Location). Absent otherwise.",
                "schema": {
                  "type": "string",
                  "enum": [
                    "true"
                  ]
                }
              },
              "X-Request-Id": {
                "$ref": "#/components/headers/RequestId"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/IssuerOnboarding"
                }
              }
            }
          },
          "400": {
            "description": "invalid_idempotency_key: the Idempotency-Key header is malformed.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "`authentication_required`: no `Authorization: Bearer` header. `invalid_api_key`: the key is malformed, unknown or revoked.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            },
            "headers": {
              "WWW-Authenticate": {
                "$ref": "#/components/headers/WwwAuthenticate"
              }
            }
          },
          "403": {
            "description": "The API key cannot perform this operation: key_scope_mismatch, key_read_only or ip_not_allowed; or its account is suspended (account_suspended).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "not_found: the issuer onboarding is not available.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "409": {
            "description": "idempotency_key_in_progress: a request with this Idempotency-Key is still running.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "413": {
            "description": "payload_too_large: the file is larger than 1 MiB.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "422": {
            "description": "validation_failed: the file or the password is missing or too long. Or idempotency_key_reused: the Idempotency-Key was used with a different request.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "apiKey": []
          }
        ],
        "summary": "Start an issuer onboarding from a .p12",
        "tags": [
          "Issuer onboardings"
        ]
      }
    },
    "/v1/issuer-onboardings/{onboardingId}": {
      "get": {
        "description": "Poll it while `verifying` (every few seconds; verification usually takes under a minute). An onboarding is deleted 30 days after it is completed, expires or is rejected, and then answers 404 `not_found`. Requires an account-scoped (global) API key with read_write access, of either mode: the certificate serves test and live documents.",
        "operationId": "issuerOnboardingsGet",
        "parameters": [
          {
            "name": "onboardingId",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          },
          {
            "$ref": "#/components/parameters/CorrelationId"
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/IssuerOnboarding"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/RequestId"
              }
            }
          },
          "401": {
            "description": "`authentication_required`: no `Authorization: Bearer` header. `invalid_api_key`: the key is malformed, unknown or revoked.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            },
            "headers": {
              "WWW-Authenticate": {
                "$ref": "#/components/headers/WwwAuthenticate"
              }
            }
          },
          "403": {
            "description": "The API key cannot perform this operation: key_scope_mismatch, key_read_only or ip_not_allowed; or its account is suspended (account_suspended).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "not_found",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "apiKey": []
          }
        ],
        "summary": "Get an issuer onboarding",
        "tags": [
          "Issuer onboardings"
        ]
      }
    },
    "/v1/issuer-onboardings/{onboardingId}/complete": {
      "post": {
        "description": "Creates the issuer with the tax profile sent (the same fields as POST /v1/issuers; start from `prefill`), its establishment 001 at the head office and emission point 001; or, when the account already has the certificate's RUC (`existingIssuer`), adds the certificate to that issuer without changing it (the body may be `{}`). The certificate serves test and live documents and starts `processing`: retrieve it under the issuer. The tax profile is the customer's responsibility. Requires an account-scoped (global) API key with read_write access, of either mode: the certificate serves test and live documents.",
        "operationId": "issuerOnboardingsComplete",
        "parameters": [
          {
            "name": "onboardingId",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "description": "Makes the request safe to retry: 1 to 255 visible ASCII characters (a UUID works well), remembered for 24 hours per account and mode. A retry with the same key and the same request returns the first successful response again, with the header `Idempotent-Replayed: true`. The same key with a different request gets 422 idempotency_key_reused; while the first request still runs, 409 idempotency_key_in_progress. A failed request does not keep its key.",
            "schema": {
              "type": "string",
              "minLength": 1,
              "maxLength": 255,
              "pattern": "^[\\x21-\\x7E]+$"
            }
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          },
          {
            "$ref": "#/components/parameters/CorrelationId"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CompleteIssuerOnboarding"
              }
            }
          }
        },
        "responses": {
          "201": {
            "headers": {
              "Location": {
                "description": "Path of the issuer: /v1/issuers/{issuer.id}. Not sent on an idempotent replay (Idempotent-Replayed: true): build it from the body as shown.",
                "schema": {
                  "type": "string"
                },
                "required": false
              },
              "Idempotent-Replayed": {
                "required": false,
                "description": "`true` when this is the stored answer of an earlier request with the same Idempotency-Key (same status and body, no Location). Absent otherwise.",
                "schema": {
                  "type": "string",
                  "enum": [
                    "true"
                  ]
                }
              },
              "X-Request-Id": {
                "$ref": "#/components/headers/RequestId"
              }
            },
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CompletedIssuerOnboarding"
                }
              }
            }
          },
          "400": {
            "description": "`malformed_json`: the body is not valid JSON. `bad_request`: the body does not decompress with its `Content-Encoding`. Or invalid_idempotency_key: the Idempotency-Key header is malformed.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "`authentication_required`: no `Authorization: Bearer` header. `invalid_api_key`: the key is malformed, unknown or revoked.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            },
            "headers": {
              "WWW-Authenticate": {
                "$ref": "#/components/headers/WwwAuthenticate"
              }
            }
          },
          "403": {
            "description": "The API key cannot perform this operation: key_scope_mismatch, key_read_only or ip_not_allowed; or its account is suspended (account_suspended).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "not_found",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "409": {
            "description": "issuer_onboarding_not_ready (still verifying), issuer_onboarding_rejected, issuer_onboarding_completed, issuer_onboarding_expired, or issuer_already_exists. Or idempotency_key_in_progress: a request with this Idempotency-Key is still running.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "413": {
            "description": "`payload_too_large`: the JSON body is larger than 1 MB.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "415": {
            "description": "`unsupported_media_type`: the body declares a charset that does not start with `utf-` (for example `latin1`, or `utf8` without the hyphen) or a `Content-Encoding` other than gzip, deflate or br.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "422": {
            "description": "validation_failed: a field of a new issuer is missing or invalid, `ruc` is required, or `ruc` does not match the certificate (ruc_mismatch). Or idempotency_key_reused: the Idempotency-Key was used with a different request.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "apiKey": []
          }
        ],
        "summary": "Complete an issuer onboarding",
        "tags": [
          "Issuer onboardings"
        ]
      }
    },
    "/v1/invoices": {
      "post": {
        "description": "Issues an invoice (factura, XML 2.1.0). Flashpi computes the line subtotals, the taxes per rate, the tip and the total with the SRI rounding rules; send expectedTotal to have a different total refused. Issuing is asynchronous: the document is validated, numbered (sequential and access key) and stored with status `processing`, and the response is 202 Accepted. Flashpi then signs it and sends it to the SRI; follow it with GET /v1/documents/{id} or webhooks. With `options.waitForAuthorization` the request waits for the SRI (15 s by default, 30 s at most) and answers 200 with the authorized, rejected or failed document, or 202 when the wait ends first. Requires a read_write API key; an issuer-scoped key can only issue for its issuer. fp_test_ keys issue in the SRI test environment, fp_live_ keys in production.",
        "operationId": "invoicesCreate",
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "description": "Makes the request safe to retry: 1 to 255 visible ASCII characters (a UUID works well), remembered for 24 hours per account and mode. A retry with the same key and the same request returns the first successful response again, with the header `Idempotent-Replayed: true`. The same key with a different request gets 422 idempotency_key_reused; while the first request still runs, 409 idempotency_key_in_progress. A failed request does not keep its key.",
            "schema": {
              "type": "string",
              "minLength": 1,
              "maxLength": 255,
              "pattern": "^[\\x21-\\x7E]+$"
            }
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          },
          {
            "$ref": "#/components/parameters/CorrelationId"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateInvoice"
              },
              "examples": {
                "example": {
                  "summary": "A complete request",
                  "value": {
                    "issuerId": "01a13eca-2e80-7c3d-9f21-5b8e4a6d0c17",
                    "establishment": "001",
                    "emissionPoint": "001",
                    "issueDate": "2026-10-15",
                    "customer": {
                      "idType": "ruc",
                      "id": "1790000000001",
                      "name": "Supermercados La Pradera S.A.",
                      "email": "compras@example.com",
                      "address": "Av. Amazonas N34-12, Quito"
                    },
                    "items": [
                      {
                        "code": "SKU-001",
                        "description": "Ground coffee 500 g",
                        "quantity": "2",
                        "unitPrice": "4.50",
                        "taxes": [
                          {
                            "type": "vat",
                            "rate": "15"
                          }
                        ]
                      }
                    ],
                    "payments": [
                      {
                        "method": "credit_card",
                        "amount": "10.35"
                      }
                    ],
                    "additionalInfo": {
                      "Order": "PO-4812"
                    },
                    "expectedTotal": "10.35",
                    "options": {
                      "sendEmail": true
                    }
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Sync mode only: the SRI settled the document within the wait (status `authorized`, `rejected` or `failed`).",
            "headers": {
              "Location": {
                "description": "Path of the document: /v1/documents/{id}. Not sent on an idempotent replay (Idempotent-Replayed: true): build it from the body as shown.",
                "schema": {
                  "type": "string"
                },
                "required": false
              },
              "Idempotent-Replayed": {
                "required": false,
                "description": "`true` when this is the stored answer of an earlier request with the same Idempotency-Key (same status and body, no Location). Absent otherwise.",
                "schema": {
                  "type": "string",
                  "enum": [
                    "true"
                  ]
                }
              },
              "X-Request-Id": {
                "$ref": "#/components/headers/RequestId"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Document"
                }
              }
            }
          },
          "202": {
            "description": "Accepted: the document is stored and is being processed (status `processing`, or `pending_sri` when a sync wait ended first).",
            "headers": {
              "Location": {
                "description": "Path of the document: /v1/documents/{id}. Not sent on an idempotent replay (Idempotent-Replayed: true): build it from the body as shown.",
                "schema": {
                  "type": "string"
                },
                "required": false
              },
              "Idempotent-Replayed": {
                "required": false,
                "description": "`true` when this is the stored answer of an earlier request with the same Idempotency-Key (same status and body, no Location). Absent otherwise.",
                "schema": {
                  "type": "string",
                  "enum": [
                    "true"
                  ]
                }
              },
              "X-Request-Id": {
                "$ref": "#/components/headers/RequestId"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Document"
                }
              }
            }
          },
          "400": {
            "description": "`malformed_json`: the body is not valid JSON. `bad_request`: the body does not decompress with its `Content-Encoding`. Or invalid_idempotency_key: the Idempotency-Key header is malformed.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "`authentication_required`: no `Authorization: Bearer` header. `invalid_api_key`: the key is malformed, unknown or revoked.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            },
            "headers": {
              "WWW-Authenticate": {
                "$ref": "#/components/headers/WwwAuthenticate"
              }
            }
          },
          "403": {
            "description": "The API key cannot perform this operation: key_scope_mismatch, key_read_only or ip_not_allowed; or its account is suspended (account_suspended). Or `sandbox_not_enabled`: `issuerId` is the shared demo issuer (sandbox) and the account's sandbox is not enabled yet (its owner has not verified their email).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "409": {
            "description": "sequential_already_used: the requested sequential is taken. sequentials_exhausted: the emission point reached sequential 999999999 for this document type. Or idempotency_key_in_progress: a request with this Idempotency-Key is still running.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "413": {
            "description": "`payload_too_large`: the JSON body is larger than 1 MB.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "415": {
            "description": "`unsupported_media_type`: the body declares a charset that does not start with `utf-` (for example `latin1`, or `utf8` without the hyphen) or a `Content-Encoding` other than gzip, deflate or br.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "422": {
            "description": "validation_failed (see errors; for example invalid_check_digit, final_consumer_not_allowed, not_in_force, unsupported_character, too_many_additional_fields, amount_mismatch, out_of_range for a sync wait above the maximum, demo_issuer_test_only or demo_issuer_sequential_not_allowed with the demo issuer), total_mismatch (expectedTotal differs from the computed total), document_too_large or document_schema_invalid. Or idempotency_key_reused: the Idempotency-Key was used with a different request.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "`demo_issuer_quota_exceeded`: `issuerId` is the shared demo issuer (sandbox) and the account already issued today's test documents with it (days follow the calendar in Ecuador). It carries `Retry-After`, `limit` and `resetsAt`; use your own issuer to issue more.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            },
            "headers": {
              "Retry-After": {
                "$ref": "#/components/headers/RetryAfter"
              }
            }
          },
          "503": {
            "description": "`demo_issuer_unavailable`: `issuerId` is the shared demo issuer (sandbox) and it cannot sign test documents now (no usable test certificate). Nothing is created; retry later or use your own issuer.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "apiKey": []
          }
        ],
        "summary": "Issue an invoice",
        "tags": [
          "Invoices"
        ]
      }
    },
    "/v1/credit-notes": {
      "post": {
        "description": "Issues a credit note (nota de crédito, XML 1.1.0) that modifies an invoice. Its VAT rates are the ones in force on the invoice date. Issuing is asynchronous: the document is validated, numbered (sequential and access key) and stored with status `processing`, and the response is 202 Accepted. Flashpi then signs it and sends it to the SRI; follow it with GET /v1/documents/{id} or webhooks. With `options.waitForAuthorization` the request waits for the SRI (15 s by default, 30 s at most) and answers 200 with the authorized, rejected or failed document, or 202 when the wait ends first. Requires a read_write API key; an issuer-scoped key can only issue for its issuer. fp_test_ keys issue in the SRI test environment, fp_live_ keys in production.",
        "operationId": "creditNotesCreate",
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "description": "Makes the request safe to retry: 1 to 255 visible ASCII characters (a UUID works well), remembered for 24 hours per account and mode. A retry with the same key and the same request returns the first successful response again, with the header `Idempotent-Replayed: true`. The same key with a different request gets 422 idempotency_key_reused; while the first request still runs, 409 idempotency_key_in_progress. A failed request does not keep its key.",
            "schema": {
              "type": "string",
              "minLength": 1,
              "maxLength": 255,
              "pattern": "^[\\x21-\\x7E]+$"
            }
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          },
          {
            "$ref": "#/components/parameters/CorrelationId"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateCreditNote"
              },
              "examples": {
                "example": {
                  "summary": "A complete request",
                  "value": {
                    "issuerId": "01a13eca-2e80-7c3d-9f21-5b8e4a6d0c17",
                    "establishment": "001",
                    "emissionPoint": "001",
                    "customer": {
                      "idType": "ruc",
                      "id": "1790000000001",
                      "name": "Supermercados La Pradera S.A.",
                      "email": "compras@example.com"
                    },
                    "modifiedDocument": {
                      "type": "invoice",
                      "number": "001-001-000000123",
                      "issueDate": "2026-10-15"
                    },
                    "reason": "Return of damaged goods",
                    "items": [
                      {
                        "code": "SKU-001",
                        "description": "Ground coffee 500 g",
                        "quantity": "1",
                        "unitPrice": "4.50",
                        "taxes": [
                          {
                            "type": "vat",
                            "rate": "15"
                          }
                        ]
                      }
                    ]
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Sync mode only: the SRI settled the document within the wait (status `authorized`, `rejected` or `failed`).",
            "headers": {
              "Location": {
                "description": "Path of the document: /v1/documents/{id}. Not sent on an idempotent replay (Idempotent-Replayed: true): build it from the body as shown.",
                "schema": {
                  "type": "string"
                },
                "required": false
              },
              "Idempotent-Replayed": {
                "required": false,
                "description": "`true` when this is the stored answer of an earlier request with the same Idempotency-Key (same status and body, no Location). Absent otherwise.",
                "schema": {
                  "type": "string",
                  "enum": [
                    "true"
                  ]
                }
              },
              "X-Request-Id": {
                "$ref": "#/components/headers/RequestId"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Document"
                }
              }
            }
          },
          "202": {
            "description": "Accepted: the document is stored and is being processed (status `processing`, or `pending_sri` when a sync wait ended first).",
            "headers": {
              "Location": {
                "description": "Path of the document: /v1/documents/{id}. Not sent on an idempotent replay (Idempotent-Replayed: true): build it from the body as shown.",
                "schema": {
                  "type": "string"
                },
                "required": false
              },
              "Idempotent-Replayed": {
                "required": false,
                "description": "`true` when this is the stored answer of an earlier request with the same Idempotency-Key (same status and body, no Location). Absent otherwise.",
                "schema": {
                  "type": "string",
                  "enum": [
                    "true"
                  ]
                }
              },
              "X-Request-Id": {
                "$ref": "#/components/headers/RequestId"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Document"
                }
              }
            }
          },
          "400": {
            "description": "`malformed_json`: the body is not valid JSON. `bad_request`: the body does not decompress with its `Content-Encoding`. Or invalid_idempotency_key: the Idempotency-Key header is malformed.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "`authentication_required`: no `Authorization: Bearer` header. `invalid_api_key`: the key is malformed, unknown or revoked.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            },
            "headers": {
              "WWW-Authenticate": {
                "$ref": "#/components/headers/WwwAuthenticate"
              }
            }
          },
          "403": {
            "description": "The API key cannot perform this operation: key_scope_mismatch, key_read_only or ip_not_allowed; or its account is suspended (account_suspended). Or `sandbox_not_enabled`: `issuerId` is the shared demo issuer (sandbox) and the account's sandbox is not enabled yet (its owner has not verified their email).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "409": {
            "description": "sequential_already_used: the requested sequential is taken. sequentials_exhausted: the emission point reached sequential 999999999 for this document type. Or idempotency_key_in_progress: a request with this Idempotency-Key is still running.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "413": {
            "description": "`payload_too_large`: the JSON body is larger than 1 MB.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "415": {
            "description": "`unsupported_media_type`: the body declares a charset that does not start with `utf-` (for example `latin1`, or `utf8` without the hyphen) or a `Content-Encoding` other than gzip, deflate or br.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "422": {
            "description": "validation_failed (see errors; for example invalid_check_digit, final_consumer_not_allowed, not_in_force, unsupported_character, too_many_additional_fields, amount_mismatch, out_of_range for a sync wait above the maximum, demo_issuer_test_only or demo_issuer_sequential_not_allowed with the demo issuer), total_mismatch (expectedTotal differs from the computed total), document_too_large or document_schema_invalid. Or idempotency_key_reused: the Idempotency-Key was used with a different request.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "`demo_issuer_quota_exceeded`: `issuerId` is the shared demo issuer (sandbox) and the account already issued today's test documents with it (days follow the calendar in Ecuador). It carries `Retry-After`, `limit` and `resetsAt`; use your own issuer to issue more.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            },
            "headers": {
              "Retry-After": {
                "$ref": "#/components/headers/RetryAfter"
              }
            }
          },
          "503": {
            "description": "`demo_issuer_unavailable`: `issuerId` is the shared demo issuer (sandbox) and it cannot sign test documents now (no usable test certificate). Nothing is created; retry later or use your own issuer.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "apiKey": []
          }
        ],
        "summary": "Issue a credit note",
        "tags": [
          "Credit notes"
        ]
      }
    },
    "/v1/debit-notes": {
      "post": {
        "description": "Issues a debit note (nota de débito, XML 1.0.0) that modifies an invoice. Its VAT rates are the ones in force on the invoice date. Issuing is asynchronous: the document is validated, numbered (sequential and access key) and stored with status `processing`, and the response is 202 Accepted. Flashpi then signs it and sends it to the SRI; follow it with GET /v1/documents/{id} or webhooks. With `options.waitForAuthorization` the request waits for the SRI (15 s by default, 30 s at most) and answers 200 with the authorized, rejected or failed document, or 202 when the wait ends first. Requires a read_write API key; an issuer-scoped key can only issue for its issuer. fp_test_ keys issue in the SRI test environment, fp_live_ keys in production.",
        "operationId": "debitNotesCreate",
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "description": "Makes the request safe to retry: 1 to 255 visible ASCII characters (a UUID works well), remembered for 24 hours per account and mode. A retry with the same key and the same request returns the first successful response again, with the header `Idempotent-Replayed: true`. The same key with a different request gets 422 idempotency_key_reused; while the first request still runs, 409 idempotency_key_in_progress. A failed request does not keep its key.",
            "schema": {
              "type": "string",
              "minLength": 1,
              "maxLength": 255,
              "pattern": "^[\\x21-\\x7E]+$"
            }
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          },
          {
            "$ref": "#/components/parameters/CorrelationId"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateDebitNote"
              },
              "examples": {
                "example": {
                  "summary": "A complete request",
                  "value": {
                    "issuerId": "01a13eca-2e80-7c3d-9f21-5b8e4a6d0c17",
                    "establishment": "001",
                    "emissionPoint": "001",
                    "customer": {
                      "idType": "ruc",
                      "id": "1790000000001",
                      "name": "Supermercados La Pradera S.A.",
                      "email": "compras@example.com"
                    },
                    "modifiedDocument": {
                      "number": "001-001-000000123",
                      "issueDate": "2026-10-15"
                    },
                    "reasons": [
                      {
                        "description": "Late payment interest",
                        "amount": "10.00",
                        "taxes": [
                          {
                            "type": "vat",
                            "rate": "15"
                          }
                        ]
                      }
                    ],
                    "payments": [
                      {
                        "method": "other_financial_system",
                        "amount": "11.50"
                      }
                    ]
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Sync mode only: the SRI settled the document within the wait (status `authorized`, `rejected` or `failed`).",
            "headers": {
              "Location": {
                "description": "Path of the document: /v1/documents/{id}. Not sent on an idempotent replay (Idempotent-Replayed: true): build it from the body as shown.",
                "schema": {
                  "type": "string"
                },
                "required": false
              },
              "Idempotent-Replayed": {
                "required": false,
                "description": "`true` when this is the stored answer of an earlier request with the same Idempotency-Key (same status and body, no Location). Absent otherwise.",
                "schema": {
                  "type": "string",
                  "enum": [
                    "true"
                  ]
                }
              },
              "X-Request-Id": {
                "$ref": "#/components/headers/RequestId"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Document"
                }
              }
            }
          },
          "202": {
            "description": "Accepted: the document is stored and is being processed (status `processing`, or `pending_sri` when a sync wait ended first).",
            "headers": {
              "Location": {
                "description": "Path of the document: /v1/documents/{id}. Not sent on an idempotent replay (Idempotent-Replayed: true): build it from the body as shown.",
                "schema": {
                  "type": "string"
                },
                "required": false
              },
              "Idempotent-Replayed": {
                "required": false,
                "description": "`true` when this is the stored answer of an earlier request with the same Idempotency-Key (same status and body, no Location). Absent otherwise.",
                "schema": {
                  "type": "string",
                  "enum": [
                    "true"
                  ]
                }
              },
              "X-Request-Id": {
                "$ref": "#/components/headers/RequestId"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Document"
                }
              }
            }
          },
          "400": {
            "description": "`malformed_json`: the body is not valid JSON. `bad_request`: the body does not decompress with its `Content-Encoding`. Or invalid_idempotency_key: the Idempotency-Key header is malformed.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "`authentication_required`: no `Authorization: Bearer` header. `invalid_api_key`: the key is malformed, unknown or revoked.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            },
            "headers": {
              "WWW-Authenticate": {
                "$ref": "#/components/headers/WwwAuthenticate"
              }
            }
          },
          "403": {
            "description": "The API key cannot perform this operation: key_scope_mismatch, key_read_only or ip_not_allowed; or its account is suspended (account_suspended). Or `sandbox_not_enabled`: `issuerId` is the shared demo issuer (sandbox) and the account's sandbox is not enabled yet (its owner has not verified their email).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "409": {
            "description": "sequential_already_used: the requested sequential is taken. sequentials_exhausted: the emission point reached sequential 999999999 for this document type. Or idempotency_key_in_progress: a request with this Idempotency-Key is still running.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "413": {
            "description": "`payload_too_large`: the JSON body is larger than 1 MB.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "415": {
            "description": "`unsupported_media_type`: the body declares a charset that does not start with `utf-` (for example `latin1`, or `utf8` without the hyphen) or a `Content-Encoding` other than gzip, deflate or br.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "422": {
            "description": "validation_failed (see errors; for example invalid_check_digit, final_consumer_not_allowed, not_in_force, unsupported_character, too_many_additional_fields, amount_mismatch, out_of_range for a sync wait above the maximum, demo_issuer_test_only or demo_issuer_sequential_not_allowed with the demo issuer), total_mismatch (expectedTotal differs from the computed total), document_too_large or document_schema_invalid. Or idempotency_key_reused: the Idempotency-Key was used with a different request.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "`demo_issuer_quota_exceeded`: `issuerId` is the shared demo issuer (sandbox) and the account already issued today's test documents with it (days follow the calendar in Ecuador). It carries `Retry-After`, `limit` and `resetsAt`; use your own issuer to issue more.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            },
            "headers": {
              "Retry-After": {
                "$ref": "#/components/headers/RetryAfter"
              }
            }
          },
          "503": {
            "description": "`demo_issuer_unavailable`: `issuerId` is the shared demo issuer (sandbox) and it cannot sign test documents now (no usable test certificate). Nothing is created; retry later or use your own issuer.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "apiKey": []
          }
        ],
        "summary": "Issue a debit note",
        "tags": [
          "Debit notes"
        ]
      }
    },
    "/v1/purchase-settlements": {
      "post": {
        "description": "Issues a purchase settlement (liquidación de compra, XML 1.1.0) for a purchase from a supplier who cannot issue invoices. Issuing is asynchronous: the document is validated, numbered (sequential and access key) and stored with status `processing`, and the response is 202 Accepted. Flashpi then signs it and sends it to the SRI; follow it with GET /v1/documents/{id} or webhooks. With `options.waitForAuthorization` the request waits for the SRI (15 s by default, 30 s at most) and answers 200 with the authorized, rejected or failed document, or 202 when the wait ends first. Requires a read_write API key; an issuer-scoped key can only issue for its issuer. fp_test_ keys issue in the SRI test environment, fp_live_ keys in production.",
        "operationId": "purchaseSettlementsCreate",
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "description": "Makes the request safe to retry: 1 to 255 visible ASCII characters (a UUID works well), remembered for 24 hours per account and mode. A retry with the same key and the same request returns the first successful response again, with the header `Idempotent-Replayed: true`. The same key with a different request gets 422 idempotency_key_reused; while the first request still runs, 409 idempotency_key_in_progress. A failed request does not keep its key.",
            "schema": {
              "type": "string",
              "minLength": 1,
              "maxLength": 255,
              "pattern": "^[\\x21-\\x7E]+$"
            }
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          },
          {
            "$ref": "#/components/parameters/CorrelationId"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreatePurchaseSettlement"
              },
              "examples": {
                "example": {
                  "summary": "A complete request",
                  "value": {
                    "issuerId": "01a13eca-2e80-7c3d-9f21-5b8e4a6d0c17",
                    "establishment": "001",
                    "emissionPoint": "001",
                    "supplier": {
                      "idType": "cedula",
                      "id": "1700000001",
                      "name": "María Fernanda Quishpe",
                      "address": "Recinto La Esperanza, Balzar"
                    },
                    "items": [
                      {
                        "code": "CACAO",
                        "description": "Dried cocoa beans",
                        "unit": "KILOGRAM",
                        "quantity": "150.5",
                        "unitPrice": "2.35",
                        "taxes": [
                          {
                            "type": "vat",
                            "rate": "0"
                          }
                        ]
                      }
                    ],
                    "payments": [
                      {
                        "method": "cash",
                        "amount": "353.68",
                        "term": "0",
                        "termUnit": "days"
                      }
                    ]
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Sync mode only: the SRI settled the document within the wait (status `authorized`, `rejected` or `failed`).",
            "headers": {
              "Location": {
                "description": "Path of the document: /v1/documents/{id}. Not sent on an idempotent replay (Idempotent-Replayed: true): build it from the body as shown.",
                "schema": {
                  "type": "string"
                },
                "required": false
              },
              "Idempotent-Replayed": {
                "required": false,
                "description": "`true` when this is the stored answer of an earlier request with the same Idempotency-Key (same status and body, no Location). Absent otherwise.",
                "schema": {
                  "type": "string",
                  "enum": [
                    "true"
                  ]
                }
              },
              "X-Request-Id": {
                "$ref": "#/components/headers/RequestId"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Document"
                }
              }
            }
          },
          "202": {
            "description": "Accepted: the document is stored and is being processed (status `processing`, or `pending_sri` when a sync wait ended first).",
            "headers": {
              "Location": {
                "description": "Path of the document: /v1/documents/{id}. Not sent on an idempotent replay (Idempotent-Replayed: true): build it from the body as shown.",
                "schema": {
                  "type": "string"
                },
                "required": false
              },
              "Idempotent-Replayed": {
                "required": false,
                "description": "`true` when this is the stored answer of an earlier request with the same Idempotency-Key (same status and body, no Location). Absent otherwise.",
                "schema": {
                  "type": "string",
                  "enum": [
                    "true"
                  ]
                }
              },
              "X-Request-Id": {
                "$ref": "#/components/headers/RequestId"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Document"
                }
              }
            }
          },
          "400": {
            "description": "`malformed_json`: the body is not valid JSON. `bad_request`: the body does not decompress with its `Content-Encoding`. Or invalid_idempotency_key: the Idempotency-Key header is malformed.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "`authentication_required`: no `Authorization: Bearer` header. `invalid_api_key`: the key is malformed, unknown or revoked.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            },
            "headers": {
              "WWW-Authenticate": {
                "$ref": "#/components/headers/WwwAuthenticate"
              }
            }
          },
          "403": {
            "description": "The API key cannot perform this operation: key_scope_mismatch, key_read_only or ip_not_allowed; or its account is suspended (account_suspended). Or `sandbox_not_enabled`: `issuerId` is the shared demo issuer (sandbox) and the account's sandbox is not enabled yet (its owner has not verified their email).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "409": {
            "description": "sequential_already_used: the requested sequential is taken. sequentials_exhausted: the emission point reached sequential 999999999 for this document type. Or idempotency_key_in_progress: a request with this Idempotency-Key is still running.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "413": {
            "description": "`payload_too_large`: the JSON body is larger than 1 MB.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "415": {
            "description": "`unsupported_media_type`: the body declares a charset that does not start with `utf-` (for example `latin1`, or `utf8` without the hyphen) or a `Content-Encoding` other than gzip, deflate or br.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "422": {
            "description": "validation_failed (see errors; for example invalid_check_digit, final_consumer_not_allowed, not_in_force, unsupported_character, too_many_additional_fields, amount_mismatch, out_of_range for a sync wait above the maximum, demo_issuer_test_only or demo_issuer_sequential_not_allowed with the demo issuer), total_mismatch (expectedTotal differs from the computed total), document_too_large or document_schema_invalid. Or idempotency_key_reused: the Idempotency-Key was used with a different request.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "`demo_issuer_quota_exceeded`: `issuerId` is the shared demo issuer (sandbox) and the account already issued today's test documents with it (days follow the calendar in Ecuador). It carries `Retry-After`, `limit` and `resetsAt`; use your own issuer to issue more.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            },
            "headers": {
              "Retry-After": {
                "$ref": "#/components/headers/RetryAfter"
              }
            }
          },
          "503": {
            "description": "`demo_issuer_unavailable`: `issuerId` is the shared demo issuer (sandbox) and it cannot sign test documents now (no usable test certificate). Nothing is created; retry later or use your own issuer.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "apiKey": []
          }
        ],
        "summary": "Issue a purchase settlement",
        "tags": [
          "Purchase settlements"
        ]
      }
    },
    "/v1/waybills": {
      "post": {
        "description": "Issues a waybill (guía de remisión, XML 1.1.0) for the transport of goods. Issuing is asynchronous: the document is validated, numbered (sequential and access key) and stored with status `processing`, and the response is 202 Accepted. Flashpi then signs it and sends it to the SRI; follow it with GET /v1/documents/{id} or webhooks. With `options.waitForAuthorization` the request waits for the SRI (15 s by default, 30 s at most) and answers 200 with the authorized, rejected or failed document, or 202 when the wait ends first. Requires a read_write API key; an issuer-scoped key can only issue for its issuer. fp_test_ keys issue in the SRI test environment, fp_live_ keys in production.",
        "operationId": "waybillsCreate",
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "description": "Makes the request safe to retry: 1 to 255 visible ASCII characters (a UUID works well), remembered for 24 hours per account and mode. A retry with the same key and the same request returns the first successful response again, with the header `Idempotent-Replayed: true`. The same key with a different request gets 422 idempotency_key_reused; while the first request still runs, 409 idempotency_key_in_progress. A failed request does not keep its key.",
            "schema": {
              "type": "string",
              "minLength": 1,
              "maxLength": 255,
              "pattern": "^[\\x21-\\x7E]+$"
            }
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          },
          {
            "$ref": "#/components/parameters/CorrelationId"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateWaybill"
              },
              "examples": {
                "example": {
                  "summary": "A complete request",
                  "value": {
                    "issuerId": "01a13eca-2e80-7c3d-9f21-5b8e4a6d0c17",
                    "establishment": "001",
                    "emissionPoint": "001",
                    "issueDate": "2026-10-15",
                    "departureAddress": "Km 12 vía a Daule, Guayaquil",
                    "carrier": {
                      "idType": "ruc",
                      "id": "0190000000001",
                      "name": "Transportes Andinos Cía. Ltda."
                    },
                    "licensePlate": "GBA1234",
                    "transportStartDate": "2026-10-15",
                    "transportEndDate": "2026-10-16",
                    "recipients": [
                      {
                        "id": "1790000000001",
                        "name": "Supermercados La Pradera S.A.",
                        "address": "Av. Amazonas N34-12, Quito",
                        "transferReason": "Sale",
                        "supportingDocument": {
                          "type": "invoice",
                          "number": "001-001-000000123",
                          "issueDate": "2026-10-15"
                        },
                        "items": [
                          {
                            "code": "SKU-001",
                            "description": "Ground coffee 500 g",
                            "quantity": "24"
                          }
                        ]
                      }
                    ]
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Sync mode only: the SRI settled the document within the wait (status `authorized`, `rejected` or `failed`).",
            "headers": {
              "Location": {
                "description": "Path of the document: /v1/documents/{id}. Not sent on an idempotent replay (Idempotent-Replayed: true): build it from the body as shown.",
                "schema": {
                  "type": "string"
                },
                "required": false
              },
              "Idempotent-Replayed": {
                "required": false,
                "description": "`true` when this is the stored answer of an earlier request with the same Idempotency-Key (same status and body, no Location). Absent otherwise.",
                "schema": {
                  "type": "string",
                  "enum": [
                    "true"
                  ]
                }
              },
              "X-Request-Id": {
                "$ref": "#/components/headers/RequestId"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Document"
                }
              }
            }
          },
          "202": {
            "description": "Accepted: the document is stored and is being processed (status `processing`, or `pending_sri` when a sync wait ended first).",
            "headers": {
              "Location": {
                "description": "Path of the document: /v1/documents/{id}. Not sent on an idempotent replay (Idempotent-Replayed: true): build it from the body as shown.",
                "schema": {
                  "type": "string"
                },
                "required": false
              },
              "Idempotent-Replayed": {
                "required": false,
                "description": "`true` when this is the stored answer of an earlier request with the same Idempotency-Key (same status and body, no Location). Absent otherwise.",
                "schema": {
                  "type": "string",
                  "enum": [
                    "true"
                  ]
                }
              },
              "X-Request-Id": {
                "$ref": "#/components/headers/RequestId"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Document"
                }
              }
            }
          },
          "400": {
            "description": "`malformed_json`: the body is not valid JSON. `bad_request`: the body does not decompress with its `Content-Encoding`. Or invalid_idempotency_key: the Idempotency-Key header is malformed.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "`authentication_required`: no `Authorization: Bearer` header. `invalid_api_key`: the key is malformed, unknown or revoked.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            },
            "headers": {
              "WWW-Authenticate": {
                "$ref": "#/components/headers/WwwAuthenticate"
              }
            }
          },
          "403": {
            "description": "The API key cannot perform this operation: key_scope_mismatch, key_read_only or ip_not_allowed; or its account is suspended (account_suspended). Or `sandbox_not_enabled`: `issuerId` is the shared demo issuer (sandbox) and the account's sandbox is not enabled yet (its owner has not verified their email).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "409": {
            "description": "sequential_already_used: the requested sequential is taken. sequentials_exhausted: the emission point reached sequential 999999999 for this document type. Or idempotency_key_in_progress: a request with this Idempotency-Key is still running.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "413": {
            "description": "`payload_too_large`: the JSON body is larger than 1 MB.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "415": {
            "description": "`unsupported_media_type`: the body declares a charset that does not start with `utf-` (for example `latin1`, or `utf8` without the hyphen) or a `Content-Encoding` other than gzip, deflate or br.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "422": {
            "description": "validation_failed (see errors; for example invalid_check_digit, final_consumer_not_allowed, not_in_force, unsupported_character, too_many_additional_fields, amount_mismatch, out_of_range for a sync wait above the maximum, demo_issuer_test_only or demo_issuer_sequential_not_allowed with the demo issuer), total_mismatch (expectedTotal differs from the computed total), document_too_large or document_schema_invalid. Or idempotency_key_reused: the Idempotency-Key was used with a different request.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "`demo_issuer_quota_exceeded`: `issuerId` is the shared demo issuer (sandbox) and the account already issued today's test documents with it (days follow the calendar in Ecuador). It carries `Retry-After`, `limit` and `resetsAt`; use your own issuer to issue more.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            },
            "headers": {
              "Retry-After": {
                "$ref": "#/components/headers/RetryAfter"
              }
            }
          },
          "503": {
            "description": "`demo_issuer_unavailable`: `issuerId` is the shared demo issuer (sandbox) and it cannot sign test documents now (no usable test certificate). Nothing is created; retry later or use your own issuer.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "apiKey": []
          }
        ],
        "summary": "Issue a waybill",
        "tags": [
          "Waybills"
        ]
      }
    },
    "/v1/withholdings": {
      "post": {
        "description": "Issues a withholding receipt (comprobante de retención, XML 2.0.0). Flashpi computes every withheld amount and the total withheld. Issuing is asynchronous: the document is validated, numbered (sequential and access key) and stored with status `processing`, and the response is 202 Accepted. Flashpi then signs it and sends it to the SRI; follow it with GET /v1/documents/{id} or webhooks. With `options.waitForAuthorization` the request waits for the SRI (15 s by default, 30 s at most) and answers 200 with the authorized, rejected or failed document, or 202 when the wait ends first. Requires a read_write API key; an issuer-scoped key can only issue for its issuer. fp_test_ keys issue in the SRI test environment, fp_live_ keys in production.",
        "operationId": "withholdingsCreate",
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "description": "Makes the request safe to retry: 1 to 255 visible ASCII characters (a UUID works well), remembered for 24 hours per account and mode. A retry with the same key and the same request returns the first successful response again, with the header `Idempotent-Replayed: true`. The same key with a different request gets 422 idempotency_key_reused; while the first request still runs, 409 idempotency_key_in_progress. A failed request does not keep its key.",
            "schema": {
              "type": "string",
              "minLength": 1,
              "maxLength": 255,
              "pattern": "^[\\x21-\\x7E]+$"
            }
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          },
          {
            "$ref": "#/components/parameters/CorrelationId"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateWithholding"
              },
              "examples": {
                "example": {
                  "summary": "A complete request",
                  "value": {
                    "issuerId": "01a13eca-2e80-7c3d-9f21-5b8e4a6d0c17",
                    "establishment": "001",
                    "emissionPoint": "001",
                    "subject": {
                      "idType": "ruc",
                      "id": "0990000000001",
                      "name": "Distribuidora del Pacífico S.A.",
                      "relatedParty": false
                    },
                    "supportingDocuments": [
                      {
                        "taxSupportCode": "01",
                        "documentTypeCode": "01",
                        "number": "001-002-000004567",
                        "issueDate": "2026-10-10",
                        "subtotal": "1000.00",
                        "total": "1150.00",
                        "taxes": [
                          {
                            "type": "vat",
                            "rate": "15",
                            "taxableBase": "1000.00"
                          }
                        ],
                        "withholdings": [
                          {
                            "tax": "income_tax",
                            "code": "312",
                            "taxableBase": "1000.00",
                            "rate": "1.75"
                          },
                          {
                            "tax": "vat",
                            "code": "1",
                            "taxableBase": "150.00"
                          }
                        ],
                        "payments": [
                          {
                            "method": "other_financial_system",
                            "amount": "1150.00"
                          }
                        ]
                      }
                    ],
                    "expectedTotal": "62.50"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Sync mode only: the SRI settled the document within the wait (status `authorized`, `rejected` or `failed`).",
            "headers": {
              "Location": {
                "description": "Path of the document: /v1/documents/{id}. Not sent on an idempotent replay (Idempotent-Replayed: true): build it from the body as shown.",
                "schema": {
                  "type": "string"
                },
                "required": false
              },
              "Idempotent-Replayed": {
                "required": false,
                "description": "`true` when this is the stored answer of an earlier request with the same Idempotency-Key (same status and body, no Location). Absent otherwise.",
                "schema": {
                  "type": "string",
                  "enum": [
                    "true"
                  ]
                }
              },
              "X-Request-Id": {
                "$ref": "#/components/headers/RequestId"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Document"
                }
              }
            }
          },
          "202": {
            "description": "Accepted: the document is stored and is being processed (status `processing`, or `pending_sri` when a sync wait ended first).",
            "headers": {
              "Location": {
                "description": "Path of the document: /v1/documents/{id}. Not sent on an idempotent replay (Idempotent-Replayed: true): build it from the body as shown.",
                "schema": {
                  "type": "string"
                },
                "required": false
              },
              "Idempotent-Replayed": {
                "required": false,
                "description": "`true` when this is the stored answer of an earlier request with the same Idempotency-Key (same status and body, no Location). Absent otherwise.",
                "schema": {
                  "type": "string",
                  "enum": [
                    "true"
                  ]
                }
              },
              "X-Request-Id": {
                "$ref": "#/components/headers/RequestId"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Document"
                }
              }
            }
          },
          "400": {
            "description": "`malformed_json`: the body is not valid JSON. `bad_request`: the body does not decompress with its `Content-Encoding`. Or invalid_idempotency_key: the Idempotency-Key header is malformed.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "`authentication_required`: no `Authorization: Bearer` header. `invalid_api_key`: the key is malformed, unknown or revoked.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            },
            "headers": {
              "WWW-Authenticate": {
                "$ref": "#/components/headers/WwwAuthenticate"
              }
            }
          },
          "403": {
            "description": "The API key cannot perform this operation: key_scope_mismatch, key_read_only or ip_not_allowed; or its account is suspended (account_suspended). Or `sandbox_not_enabled`: `issuerId` is the shared demo issuer (sandbox) and the account's sandbox is not enabled yet (its owner has not verified their email).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "409": {
            "description": "sequential_already_used: the requested sequential is taken. sequentials_exhausted: the emission point reached sequential 999999999 for this document type. Or idempotency_key_in_progress: a request with this Idempotency-Key is still running.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "413": {
            "description": "`payload_too_large`: the JSON body is larger than 1 MB.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "415": {
            "description": "`unsupported_media_type`: the body declares a charset that does not start with `utf-` (for example `latin1`, or `utf8` without the hyphen) or a `Content-Encoding` other than gzip, deflate or br.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "422": {
            "description": "validation_failed (see errors; for example invalid_check_digit, final_consumer_not_allowed, not_in_force, unsupported_character, too_many_additional_fields, amount_mismatch, out_of_range for a sync wait above the maximum, demo_issuer_test_only or demo_issuer_sequential_not_allowed with the demo issuer), total_mismatch (expectedTotal differs from the computed total), document_too_large or document_schema_invalid. Or idempotency_key_reused: the Idempotency-Key was used with a different request.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "`demo_issuer_quota_exceeded`: `issuerId` is the shared demo issuer (sandbox) and the account already issued today's test documents with it (days follow the calendar in Ecuador). It carries `Retry-After`, `limit` and `resetsAt`; use your own issuer to issue more.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            },
            "headers": {
              "Retry-After": {
                "$ref": "#/components/headers/RetryAfter"
              }
            }
          },
          "503": {
            "description": "`demo_issuer_unavailable`: `issuerId` is the shared demo issuer (sandbox) and it cannot sign test documents now (no usable test certificate). Nothing is created; retry later or use your own issuer.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "apiKey": []
          }
        ],
        "summary": "Issue a withholding receipt",
        "tags": [
          "Withholdings"
        ]
      }
    },
    "/v1/documents": {
      "get": {
        "description": "Documents of every type, newest first, with optional filters. Any API key can read (read_only included); an issuer-scoped key only sees its issuer. Test keys see test documents and live keys live documents.",
        "operationId": "documentsList",
        "parameters": [
          {
            "name": "limit",
            "required": false,
            "in": "query",
            "description": "Maximum number of items to return.",
            "schema": {
              "minimum": 1,
              "maximum": 100,
              "default": 20,
              "type": "integer"
            }
          },
          {
            "name": "cursor",
            "required": false,
            "in": "query",
            "description": "The `pagination.nextCursor` of the previous page. Omit it for the first page.",
            "schema": {
              "maxLength": 200,
              "type": "string"
            }
          },
          {
            "name": "issuerId",
            "required": false,
            "in": "query",
            "description": "Only documents of this issuer.",
            "schema": {
              "format": "uuid",
              "type": "string"
            }
          },
          {
            "name": "type",
            "required": false,
            "in": "query",
            "description": "Only this document type.",
            "schema": {
              "type": "string",
              "enum": [
                "invoice",
                "purchase_settlement",
                "credit_note",
                "debit_note",
                "waybill",
                "withholding"
              ]
            }
          },
          {
            "name": "status",
            "required": false,
            "in": "query",
            "description": "Only this tax status.",
            "schema": {
              "type": "string",
              "enum": [
                "processing",
                "pending_sri",
                "authorized",
                "rejected",
                "failed",
                "voided"
              ]
            }
          },
          {
            "name": "issueDateFrom",
            "required": false,
            "in": "query",
            "description": "Only documents issued on or after this date.",
            "schema": {
              "format": "date",
              "example": "2026-10-01",
              "type": "string"
            }
          },
          {
            "name": "issueDateTo",
            "required": false,
            "in": "query",
            "description": "Only documents issued on or before this date.",
            "schema": {
              "format": "date",
              "example": "2026-10-31",
              "type": "string"
            }
          },
          {
            "name": "counterpartyId",
            "required": false,
            "in": "query",
            "description": "Only documents of this buyer, supplier, withheld subject or carrier.",
            "schema": {
              "maxLength": 20,
              "example": "1790000000001",
              "type": "string"
            }
          },
          {
            "name": "accessKey",
            "required": false,
            "in": "query",
            "description": "The document with this access key.",
            "schema": {
              "pattern": "^\\d{49}$",
              "type": "string"
            }
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          },
          {
            "$ref": "#/components/parameters/CorrelationId"
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DocumentList"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/RequestId"
              }
            }
          },
          "401": {
            "description": "`authentication_required`: no `Authorization: Bearer` header. `invalid_api_key`: the key is malformed, unknown or revoked.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            },
            "headers": {
              "WWW-Authenticate": {
                "$ref": "#/components/headers/WwwAuthenticate"
              }
            }
          },
          "403": {
            "description": "The API key cannot perform this operation: key_scope_mismatch, key_read_only or ip_not_allowed; or its account is suspended (account_suspended).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "422": {
            "description": "validation_failed: invalid limit, cursor or filter.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "apiKey": []
          }
        ],
        "summary": "List documents",
        "tags": [
          "Documents"
        ]
      }
    },
    "/v1/documents/{documentId}": {
      "get": {
        "description": "Any API key can read (read_only included); an issuer-scoped key only sees its issuer. Test keys see test documents and live keys live documents.",
        "operationId": "documentsGet",
        "parameters": [
          {
            "name": "documentId",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          },
          {
            "$ref": "#/components/parameters/CorrelationId"
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Document"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/RequestId"
              }
            }
          },
          "401": {
            "description": "`authentication_required`: no `Authorization: Bearer` header. `invalid_api_key`: the key is malformed, unknown or revoked.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            },
            "headers": {
              "WWW-Authenticate": {
                "$ref": "#/components/headers/WwwAuthenticate"
              }
            }
          },
          "403": {
            "description": "The API key cannot perform this operation: key_scope_mismatch, key_read_only or ip_not_allowed; or its account is suspended (account_suspended).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "not_found",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "apiKey": []
          }
        ],
        "summary": "Get a document",
        "tags": [
          "Documents"
        ]
      }
    },
    "/v1/documents/{documentId}/xml": {
      "get": {
        "description": "The most advanced XML available: the authorized XML once the SRI authorized the document, else the signed XML, else the unsigned XML Flashpi built. The `Flashpi-Xml-Kind` header says which one (authorized, signed or unsigned). Any API key can read (read_only included); an issuer-scoped key only sees its issuer. Test keys see test documents and live keys live documents.",
        "operationId": "documentsGetXml",
        "parameters": [
          {
            "name": "documentId",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          },
          {
            "$ref": "#/components/parameters/CorrelationId"
          }
        ],
        "responses": {
          "200": {
            "description": "The XML document.",
            "content": {
              "application/xml": {
                "schema": {
                  "type": "string"
                }
              }
            },
            "headers": {
              "Flashpi-Xml-Kind": {
                "description": "`authorized`, `signed` or `unsigned`.",
                "schema": {
                  "type": "string",
                  "enum": [
                    "authorized",
                    "signed",
                    "unsigned"
                  ]
                }
              },
              "X-Request-Id": {
                "$ref": "#/components/headers/RequestId"
              }
            }
          },
          "401": {
            "description": "`authentication_required`: no `Authorization: Bearer` header. `invalid_api_key`: the key is malformed, unknown or revoked.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            },
            "headers": {
              "WWW-Authenticate": {
                "$ref": "#/components/headers/WwwAuthenticate"
              }
            }
          },
          "403": {
            "description": "The API key cannot perform this operation: key_scope_mismatch, key_read_only or ip_not_allowed; or its account is suspended (account_suspended).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "not_found: no such document, or a test document whose files were deleted (the files of test documents are kept 90 days after they are stored; the detail says so).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "apiKey": []
          }
        ],
        "summary": "Get the XML of a document",
        "tags": [
          "Documents"
        ]
      }
    },
    "/v1/documents/{documentId}/pdf": {
      "get": {
        "description": "The RIDE, the printed representation of the authorized document, in the template of the account (`modern` unless the account chose `classic` or `minimal`) with the issuer's branding. It is generated once the SRI authorizes the document; until then, or when its generation failed, the answer is 409 `ride_not_available` with the `rideStatus`. Any API key can read (read_only included); an issuer-scoped key only sees its issuer. Test keys see test documents and live keys live documents.",
        "operationId": "documentsGetPdf",
        "parameters": [
          {
            "name": "documentId",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          },
          {
            "$ref": "#/components/parameters/CorrelationId"
          }
        ],
        "responses": {
          "200": {
            "description": "The RIDE as a PDF/A-2b file.",
            "content": {
              "application/pdf": {
                "schema": {
                  "type": "string",
                  "format": "binary"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/RequestId"
              }
            }
          },
          "401": {
            "description": "`authentication_required`: no `Authorization: Bearer` header. `invalid_api_key`: the key is malformed, unknown or revoked.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            },
            "headers": {
              "WWW-Authenticate": {
                "$ref": "#/components/headers/WwwAuthenticate"
              }
            }
          },
          "403": {
            "description": "The API key cannot perform this operation: key_scope_mismatch, key_read_only or ip_not_allowed; or its account is suspended (account_suspended).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "not_found: no such document, or a test document whose files were deleted (the files of test documents are kept 90 days after they are stored; the detail says so).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "409": {
            "description": "ride_not_available: the RIDE is pending (the document is not authorized yet, or it is being generated) or failed; see `rideStatus`.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "apiKey": []
          }
        ],
        "summary": "Get the RIDE (PDF) of a document",
        "tags": [
          "Documents"
        ]
      }
    },
    "/v1/documents/{documentId}/email": {
      "post": {
        "description": "Emails the authorized document (RIDE PDF and XML) to the email address of its request, also when the email was not requested when it was issued. A new delivery appears in `email.deliveries` and `email.status` becomes `queued`; the email goes out once the RIDE exists (a failed RIDE is generated again first). Follow it with GET /v1/documents/{id} or the `document.email.*` events. Requires a read_write API key; an issuer-scoped key only reaches its issuer.\n\nDaily limits (calendar days in Ecuador, UTC-5): a document can be emailed again at most 3 times a day in test mode, and an account queues at most 20 test emails a day (automatic emails of authorized documents and resends together). Live limits default to 10 resends per document and 200 emails per account a day, and Flashpi queues a limited number of emails a day across all accounts. Beyond them the answer is 429 with `Retry-After` and `resetsAt` (the next midnight in Ecuador), plus the `limit` of an account or document limit; an automatic email beyond a limit becomes a failed delivery with the error `account_email_limit_reached` or `platform_email_limit_reached`.\n\nTest mode: documents are only emailed to verified email addresses of the account's team members (console users who verified their address). Any other recipient is never emailed: the automatic email becomes a failed delivery with the error `test_recipient_not_allowed`, and this endpoint answers 409. Live documents are not restricted this way.",
        "operationId": "documentsSendEmail",
        "parameters": [
          {
            "name": "documentId",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "description": "Makes the request safe to retry: 1 to 255 visible ASCII characters (a UUID works well), remembered for 24 hours per account and mode. A retry with the same key and the same request returns the first successful response again, with the header `Idempotent-Replayed: true`. The same key with a different request gets 422 idempotency_key_reused; while the first request still runs, 409 idempotency_key_in_progress. A failed request does not keep its key.",
            "schema": {
              "type": "string",
              "minLength": 1,
              "maxLength": 255,
              "pattern": "^[\\x21-\\x7E]+$"
            }
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          },
          {
            "$ref": "#/components/parameters/CorrelationId"
          }
        ],
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/SendDocumentEmail"
              }
            }
          }
        },
        "responses": {
          "202": {
            "description": "The email is queued.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Document"
                }
              }
            },
            "headers": {
              "Idempotent-Replayed": {
                "required": false,
                "description": "`true` when this is the stored answer of an earlier request with the same Idempotency-Key (same status and body, no Location). Absent otherwise.",
                "schema": {
                  "type": "string",
                  "enum": [
                    "true"
                  ]
                }
              },
              "X-Request-Id": {
                "$ref": "#/components/headers/RequestId"
              }
            }
          },
          "400": {
            "description": "`malformed_json`: the body is not valid JSON. `bad_request`: the body does not decompress with its `Content-Encoding`. Or invalid_idempotency_key: the Idempotency-Key header is malformed.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "`authentication_required`: no `Authorization: Bearer` header. `invalid_api_key`: the key is malformed, unknown or revoked.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            },
            "headers": {
              "WWW-Authenticate": {
                "$ref": "#/components/headers/WwwAuthenticate"
              }
            }
          },
          "403": {
            "description": "The API key cannot perform this operation: key_scope_mismatch, key_read_only or ip_not_allowed; or its account is suspended (account_suspended).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "not_found",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "409": {
            "description": "document_not_authorized: only authorized documents are emailed; see `documentStatus`. email_recipient_missing: the request had no email address. email_already_queued: an email of the document is still waiting to be sent. email_sending_paused: the account's emails of this mode are paused (see `environment`). test_recipient_not_allowed: a test document whose recipient is not a verified member of the account's team. Or idempotency_key_in_progress: a request with this Idempotency-Key is still running.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "413": {
            "description": "`payload_too_large`: the JSON body is larger than 1 MB.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "415": {
            "description": "`unsupported_media_type`: the body declares a charset that does not start with `utf-` (for example `latin1`, or `utf8` without the hyphen) or a `Content-Encoding` other than gzip, deflate or br.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "422": {
            "description": "idempotency_key_reused: the Idempotency-Key was used with a different request.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "email_resend_limit_reached: the document's resends of today are used up. account_email_limit_reached: the account's emails of today in this mode are used up. Both carry `Retry-After`, `limit` and `resetsAt`. platform_email_limit_reached: Flashpi's emails of today across all accounts are used up; it carries `Retry-After` and `resetsAt`.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            },
            "headers": {
              "Retry-After": {
                "$ref": "#/components/headers/RetryAfter"
              }
            }
          }
        },
        "security": [
          {
            "apiKey": []
          }
        ],
        "summary": "Email a document again",
        "tags": [
          "Documents"
        ]
      }
    },
    "/v1/webhook-endpoints": {
      "post": {
        "description": "Registers a public HTTPS URL for the chosen event types. The endpoint starts `pending_verification`: Flashpi POSTs a signed `webhook_endpoint.verification` body with a `challenge`, and the endpoint must answer 2xx echoing it (`{\"challenge\": \"...\"}`, or the challenge as plain text) before it receives events. Read its signing secret with GET .../secret. Requires an account-scoped (global) API key with read_write access. Test keys manage the endpoints of test events and live keys those of live events.",
        "operationId": "webhookEndpointsCreate",
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "description": "Makes the request safe to retry: 1 to 255 visible ASCII characters (a UUID works well), remembered for 24 hours per account and mode. A retry with the same key and the same request returns the first successful response again, with the header `Idempotent-Replayed: true`. The same key with a different request gets 422 idempotency_key_reused; while the first request still runs, 409 idempotency_key_in_progress. A failed request does not keep its key.",
            "schema": {
              "type": "string",
              "minLength": 1,
              "maxLength": 255,
              "pattern": "^[\\x21-\\x7E]+$"
            }
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          },
          {
            "$ref": "#/components/parameters/CorrelationId"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateWebhookEndpoint"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/WebhookEndpoint"
                }
              }
            },
            "headers": {
              "Idempotent-Replayed": {
                "required": false,
                "description": "`true` when this is the stored answer of an earlier request with the same Idempotency-Key (same status and body, no Location). Absent otherwise.",
                "schema": {
                  "type": "string",
                  "enum": [
                    "true"
                  ]
                }
              },
              "X-Request-Id": {
                "$ref": "#/components/headers/RequestId"
              }
            }
          },
          "400": {
            "description": "`malformed_json`: the body is not valid JSON. `bad_request`: the body does not decompress with its `Content-Encoding`. Or invalid_idempotency_key: the Idempotency-Key header is malformed.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "`authentication_required`: no `Authorization: Bearer` header. `invalid_api_key`: the key is malformed, unknown or revoked.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            },
            "headers": {
              "WWW-Authenticate": {
                "$ref": "#/components/headers/WwwAuthenticate"
              }
            }
          },
          "403": {
            "description": "The API key cannot perform this operation: key_scope_mismatch, key_read_only or ip_not_allowed; or its account is suspended (account_suspended).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "409": {
            "description": "idempotency_key_in_progress: a request with this Idempotency-Key is still running.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "413": {
            "description": "`payload_too_large`: the JSON body is larger than 1 MB.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "415": {
            "description": "`unsupported_media_type`: the body declares a charset that does not start with `utf-` (for example `latin1`, or `utf8` without the hyphen) or a `Content-Encoding` other than gzip, deflate or br.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "422": {
            "description": "validation_failed: see errors (url_not_allowed for a URL that is not public HTTPS). Or idempotency_key_reused: the Idempotency-Key was used with a different request.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "apiKey": []
          }
        ],
        "summary": "Create a webhook endpoint",
        "tags": [
          "Webhooks"
        ]
      },
      "get": {
        "description": "Newest first. Requires an account-scoped (global) API key with read_write access. Test keys manage the endpoints of test events and live keys those of live events.",
        "operationId": "webhookEndpointsList",
        "parameters": [
          {
            "name": "limit",
            "required": false,
            "in": "query",
            "description": "Maximum number of items to return.",
            "schema": {
              "minimum": 1,
              "maximum": 100,
              "default": 20,
              "type": "integer"
            }
          },
          {
            "name": "cursor",
            "required": false,
            "in": "query",
            "description": "The `pagination.nextCursor` of the previous page. Omit it for the first page.",
            "schema": {
              "maxLength": 200,
              "type": "string"
            }
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          },
          {
            "$ref": "#/components/parameters/CorrelationId"
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/WebhookEndpointList"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/RequestId"
              }
            }
          },
          "401": {
            "description": "`authentication_required`: no `Authorization: Bearer` header. `invalid_api_key`: the key is malformed, unknown or revoked.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            },
            "headers": {
              "WWW-Authenticate": {
                "$ref": "#/components/headers/WwwAuthenticate"
              }
            }
          },
          "403": {
            "description": "The API key cannot perform this operation: key_scope_mismatch, key_read_only or ip_not_allowed; or its account is suspended (account_suspended).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "422": {
            "description": "validation_failed: invalid limit or cursor.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "apiKey": []
          }
        ],
        "summary": "List webhook endpoints",
        "tags": [
          "Webhooks"
        ]
      }
    },
    "/v1/webhook-endpoints/{endpointId}": {
      "get": {
        "description": "Requires an account-scoped (global) API key with read_write access. Test keys manage the endpoints of test events and live keys those of live events.",
        "operationId": "webhookEndpointsGet",
        "parameters": [
          {
            "name": "endpointId",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          },
          {
            "$ref": "#/components/parameters/CorrelationId"
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/WebhookEndpoint"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/RequestId"
              }
            }
          },
          "401": {
            "description": "`authentication_required`: no `Authorization: Bearer` header. `invalid_api_key`: the key is malformed, unknown or revoked.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            },
            "headers": {
              "WWW-Authenticate": {
                "$ref": "#/components/headers/WwwAuthenticate"
              }
            }
          },
          "403": {
            "description": "The API key cannot perform this operation: key_scope_mismatch, key_read_only or ip_not_allowed; or its account is suspended (account_suspended).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "not_found",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "apiKey": []
          }
        ],
        "summary": "Get a webhook endpoint",
        "tags": [
          "Webhooks"
        ]
      },
      "patch": {
        "description": "Changes the fields sent. A new URL goes back to `pending_verification` and gets a new handshake; `disabled: true` stops deliveries (pending ones end) and `disabled: false` enables the endpoint again. Requires an account-scoped (global) API key with read_write access. Test keys manage the endpoints of test events and live keys those of live events.",
        "operationId": "webhookEndpointsUpdate",
        "parameters": [
          {
            "name": "endpointId",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          },
          {
            "$ref": "#/components/parameters/CorrelationId"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/UpdateWebhookEndpoint"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/WebhookEndpoint"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/RequestId"
              }
            }
          },
          "400": {
            "description": "`malformed_json`: the body is not valid JSON. `bad_request`: the body does not decompress with its `Content-Encoding`.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "`authentication_required`: no `Authorization: Bearer` header. `invalid_api_key`: the key is malformed, unknown or revoked.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            },
            "headers": {
              "WWW-Authenticate": {
                "$ref": "#/components/headers/WwwAuthenticate"
              }
            }
          },
          "403": {
            "description": "The API key cannot perform this operation: key_scope_mismatch, key_read_only or ip_not_allowed; or its account is suspended (account_suspended).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "not_found",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "409": {
            "description": "conflict: the endpoint changed at the same time; try again.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "413": {
            "description": "`payload_too_large`: the JSON body is larger than 1 MB.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "415": {
            "description": "`unsupported_media_type`: the body declares a charset that does not start with `utf-` (for example `latin1`, or `utf8` without the hyphen) or a `Content-Encoding` other than gzip, deflate or br.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "422": {
            "description": "validation_failed: see errors.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "apiKey": []
          }
        ],
        "summary": "Update a webhook endpoint",
        "tags": [
          "Webhooks"
        ]
      },
      "delete": {
        "description": "Deletes the endpoint and its delivery log; the events stay. Requires an account-scoped (global) API key with read_write access. Test keys manage the endpoints of test events and live keys those of live events.",
        "operationId": "webhookEndpointsDelete",
        "parameters": [
          {
            "name": "endpointId",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          },
          {
            "$ref": "#/components/parameters/CorrelationId"
          }
        ],
        "responses": {
          "204": {
            "description": "Deleted.",
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/RequestId"
              }
            }
          },
          "401": {
            "description": "`authentication_required`: no `Authorization: Bearer` header. `invalid_api_key`: the key is malformed, unknown or revoked.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            },
            "headers": {
              "WWW-Authenticate": {
                "$ref": "#/components/headers/WwwAuthenticate"
              }
            }
          },
          "403": {
            "description": "The API key cannot perform this operation: key_scope_mismatch, key_read_only or ip_not_allowed; or its account is suspended (account_suspended).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "not_found",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "apiKey": []
          }
        ],
        "summary": "Delete a webhook endpoint",
        "tags": [
          "Webhooks"
        ]
      }
    },
    "/v1/webhook-endpoints/{endpointId}/secret": {
      "get": {
        "description": "The whsec_ secret that signs the deliveries (Standard Webhooks, HMAC-SHA256). It is stored encrypted and only returned here. Requires an account-scoped (global) API key with read_write access. Test keys manage the endpoints of test events and live keys those of live events.",
        "operationId": "webhookEndpointsSecret",
        "parameters": [
          {
            "name": "endpointId",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          },
          {
            "$ref": "#/components/parameters/CorrelationId"
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/WebhookEndpointSecret"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/RequestId"
              }
            }
          },
          "401": {
            "description": "`authentication_required`: no `Authorization: Bearer` header. `invalid_api_key`: the key is malformed, unknown or revoked.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            },
            "headers": {
              "WWW-Authenticate": {
                "$ref": "#/components/headers/WwwAuthenticate"
              }
            }
          },
          "403": {
            "description": "The API key cannot perform this operation: key_scope_mismatch, key_read_only or ip_not_allowed; or its account is suspended (account_suspended).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "not_found",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "apiKey": []
          }
        ],
        "summary": "Get the signing secret of a webhook endpoint",
        "tags": [
          "Webhooks"
        ]
      }
    },
    "/v1/webhook-endpoints/{endpointId}/rotate-secret": {
      "post": {
        "description": "Creates a new secret (read it with GET .../secret). Until previousSecretExpiresAt, every delivery carries a signature with each secret, so receivers can switch without losing events. Requires an account-scoped (global) API key with read_write access. Test keys manage the endpoints of test events and live keys those of live events.",
        "operationId": "webhookEndpointsRotateSecret",
        "parameters": [
          {
            "name": "endpointId",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "description": "Makes the request safe to retry: 1 to 255 visible ASCII characters (a UUID works well), remembered for 24 hours per account and mode. A retry with the same key and the same request returns the first successful response again, with the header `Idempotent-Replayed: true`. The same key with a different request gets 422 idempotency_key_reused; while the first request still runs, 409 idempotency_key_in_progress. A failed request does not keep its key.",
            "schema": {
              "type": "string",
              "minLength": 1,
              "maxLength": 255,
              "pattern": "^[\\x21-\\x7E]+$"
            }
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          },
          {
            "$ref": "#/components/parameters/CorrelationId"
          }
        ],
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/RotateWebhookEndpointSecret"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/WebhookEndpoint"
                }
              }
            },
            "headers": {
              "Idempotent-Replayed": {
                "required": false,
                "description": "`true` when this is the stored answer of an earlier request with the same Idempotency-Key (same status and body, no Location). Absent otherwise.",
                "schema": {
                  "type": "string",
                  "enum": [
                    "true"
                  ]
                }
              },
              "X-Request-Id": {
                "$ref": "#/components/headers/RequestId"
              }
            }
          },
          "400": {
            "description": "`malformed_json`: the body is not valid JSON. `bad_request`: the body does not decompress with its `Content-Encoding`. Or invalid_idempotency_key: the Idempotency-Key header is malformed.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "`authentication_required`: no `Authorization: Bearer` header. `invalid_api_key`: the key is malformed, unknown or revoked.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            },
            "headers": {
              "WWW-Authenticate": {
                "$ref": "#/components/headers/WwwAuthenticate"
              }
            }
          },
          "403": {
            "description": "The API key cannot perform this operation: key_scope_mismatch, key_read_only or ip_not_allowed; or its account is suspended (account_suspended).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "not_found",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "409": {
            "description": "conflict: rotated by another request at the same time. Or idempotency_key_in_progress: a request with this Idempotency-Key is still running.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "413": {
            "description": "`payload_too_large`: the JSON body is larger than 1 MB.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "415": {
            "description": "`unsupported_media_type`: the body declares a charset that does not start with `utf-` (for example `latin1`, or `utf8` without the hyphen) or a `Content-Encoding` other than gzip, deflate or br.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "422": {
            "description": "validation_failed: see errors. Or idempotency_key_reused: the Idempotency-Key was used with a different request.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "apiKey": []
          }
        ],
        "summary": "Rotate the signing secret of a webhook endpoint",
        "tags": [
          "Webhooks"
        ]
      }
    },
    "/v1/webhook-endpoints/{endpointId}/verify": {
      "post": {
        "description": "Starts a new handshake for an endpoint that is still `pending_verification` (for example after fixing the receiver); follow it with GET. Requires an account-scoped (global) API key with read_write access. Test keys manage the endpoints of test events and live keys those of live events.",
        "operationId": "webhookEndpointsVerify",
        "parameters": [
          {
            "name": "endpointId",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "description": "Makes the request safe to retry: 1 to 255 visible ASCII characters (a UUID works well), remembered for 24 hours per account and mode. A retry with the same key and the same request returns the first successful response again, with the header `Idempotent-Replayed: true`. The same key with a different request gets 422 idempotency_key_reused; while the first request still runs, 409 idempotency_key_in_progress. A failed request does not keep its key.",
            "schema": {
              "type": "string",
              "minLength": 1,
              "maxLength": 255,
              "pattern": "^[\\x21-\\x7E]+$"
            }
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          },
          {
            "$ref": "#/components/parameters/CorrelationId"
          }
        ],
        "responses": {
          "202": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/WebhookEndpoint"
                }
              }
            },
            "headers": {
              "Idempotent-Replayed": {
                "required": false,
                "description": "`true` when this is the stored answer of an earlier request with the same Idempotency-Key (same status and body, no Location). Absent otherwise.",
                "schema": {
                  "type": "string",
                  "enum": [
                    "true"
                  ]
                }
              },
              "X-Request-Id": {
                "$ref": "#/components/headers/RequestId"
              }
            }
          },
          "400": {
            "description": "invalid_idempotency_key: the Idempotency-Key header is malformed.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "`authentication_required`: no `Authorization: Bearer` header. `invalid_api_key`: the key is malformed, unknown or revoked.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            },
            "headers": {
              "WWW-Authenticate": {
                "$ref": "#/components/headers/WwwAuthenticate"
              }
            }
          },
          "403": {
            "description": "The API key cannot perform this operation: key_scope_mismatch, key_read_only or ip_not_allowed; or its account is suspended (account_suspended).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "not_found",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "409": {
            "description": "webhook_endpoint_already_verified, or webhook_endpoint_disabled: enable it first. Or idempotency_key_in_progress: a request with this Idempotency-Key is still running.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "422": {
            "description": "idempotency_key_reused: the Idempotency-Key was used with a different request.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "apiKey": []
          }
        ],
        "summary": "Send the verification challenge again",
        "tags": [
          "Webhooks"
        ]
      }
    },
    "/v1/webhook-endpoints/{endpointId}/deliveries": {
      "get": {
        "description": "The delivery log, newest first. Requires an account-scoped (global) API key with read_write access. Test keys manage the endpoints of test events and live keys those of live events.",
        "operationId": "webhookEndpointsDeliveriesList",
        "parameters": [
          {
            "name": "endpointId",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "limit",
            "required": false,
            "in": "query",
            "description": "Maximum number of items to return.",
            "schema": {
              "minimum": 1,
              "maximum": 100,
              "default": 20,
              "type": "integer"
            }
          },
          {
            "name": "cursor",
            "required": false,
            "in": "query",
            "description": "The `pagination.nextCursor` of the previous page. Omit it for the first page.",
            "schema": {
              "maxLength": 200,
              "type": "string"
            }
          },
          {
            "name": "status",
            "required": false,
            "in": "query",
            "description": "Only deliveries in this status.",
            "schema": {
              "type": "string",
              "enum": [
                "pending",
                "succeeded",
                "failed"
              ]
            }
          },
          {
            "name": "eventType",
            "required": false,
            "in": "query",
            "description": "Only deliveries of this event type.",
            "schema": {
              "type": "string",
              "enum": [
                "invoice.authorized",
                "invoice.rejected",
                "purchase_settlement.authorized",
                "purchase_settlement.rejected",
                "credit_note.authorized",
                "credit_note.rejected",
                "debit_note.authorized",
                "debit_note.rejected",
                "waybill.authorized",
                "waybill.rejected",
                "withholding.authorized",
                "withholding.rejected",
                "certificate.verified",
                "certificate.pending",
                "certificate.blocked",
                "certificate.revoked",
                "certificate.reactivated",
                "document.ride.generated",
                "document.ride.failed",
                "document.email.sent",
                "document.email.delivered",
                "document.email.bounced",
                "document.email.complained",
                "document.email.failed",
                "account.email_paused",
                "account.email_resumed"
              ]
            }
          },
          {
            "name": "eventId",
            "required": false,
            "in": "query",
            "description": "Only the delivery of this event.",
            "schema": {
              "format": "uuid",
              "type": "string"
            }
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          },
          {
            "$ref": "#/components/parameters/CorrelationId"
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/WebhookDeliveryList"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/RequestId"
              }
            }
          },
          "401": {
            "description": "`authentication_required`: no `Authorization: Bearer` header. `invalid_api_key`: the key is malformed, unknown or revoked.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            },
            "headers": {
              "WWW-Authenticate": {
                "$ref": "#/components/headers/WwwAuthenticate"
              }
            }
          },
          "403": {
            "description": "The API key cannot perform this operation: key_scope_mismatch, key_read_only or ip_not_allowed; or its account is suspended (account_suspended).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "not_found",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "422": {
            "description": "validation_failed: invalid filter, limit or cursor.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "apiKey": []
          }
        ],
        "summary": "List the deliveries of a webhook endpoint",
        "tags": [
          "Webhooks"
        ]
      }
    },
    "/v1/webhook-endpoints/{endpointId}/deliveries/{deliveryId}": {
      "get": {
        "description": "A delivery with every attempt (status, duration, error). Requires an account-scoped (global) API key with read_write access. Test keys manage the endpoints of test events and live keys those of live events.",
        "operationId": "webhookEndpointsDeliveriesGet",
        "parameters": [
          {
            "name": "endpointId",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "deliveryId",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          },
          {
            "$ref": "#/components/parameters/CorrelationId"
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/WebhookDeliveryDetail"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/RequestId"
              }
            }
          },
          "401": {
            "description": "`authentication_required`: no `Authorization: Bearer` header. `invalid_api_key`: the key is malformed, unknown or revoked.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            },
            "headers": {
              "WWW-Authenticate": {
                "$ref": "#/components/headers/WwwAuthenticate"
              }
            }
          },
          "403": {
            "description": "The API key cannot perform this operation: key_scope_mismatch, key_read_only or ip_not_allowed; or its account is suspended (account_suspended).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "not_found",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "apiKey": []
          }
        ],
        "summary": "Get a webhook delivery",
        "tags": [
          "Webhooks"
        ]
      }
    },
    "/v1/webhook-endpoints/{endpointId}/deliveries/{deliveryId}/replay": {
      "post": {
        "description": "Sends a delivery that succeeded or failed again, once, right away: the same event and webhook-id with a new timestamp and signature. Requires an account-scoped (global) API key with read_write access. Test keys manage the endpoints of test events and live keys those of live events.",
        "operationId": "webhookEndpointsDeliveriesReplay",
        "parameters": [
          {
            "name": "endpointId",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "deliveryId",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "description": "Makes the request safe to retry: 1 to 255 visible ASCII characters (a UUID works well), remembered for 24 hours per account and mode. A retry with the same key and the same request returns the first successful response again, with the header `Idempotent-Replayed: true`. The same key with a different request gets 422 idempotency_key_reused; while the first request still runs, 409 idempotency_key_in_progress. A failed request does not keep its key.",
            "schema": {
              "type": "string",
              "minLength": 1,
              "maxLength": 255,
              "pattern": "^[\\x21-\\x7E]+$"
            }
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          },
          {
            "$ref": "#/components/parameters/CorrelationId"
          }
        ],
        "responses": {
          "202": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/WebhookDeliveryDetail"
                }
              }
            },
            "headers": {
              "Idempotent-Replayed": {
                "required": false,
                "description": "`true` when this is the stored answer of an earlier request with the same Idempotency-Key (same status and body, no Location). Absent otherwise.",
                "schema": {
                  "type": "string",
                  "enum": [
                    "true"
                  ]
                }
              },
              "X-Request-Id": {
                "$ref": "#/components/headers/RequestId"
              }
            }
          },
          "400": {
            "description": "invalid_idempotency_key: the Idempotency-Key header is malformed.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "`authentication_required`: no `Authorization: Bearer` header. `invalid_api_key`: the key is malformed, unknown or revoked.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            },
            "headers": {
              "WWW-Authenticate": {
                "$ref": "#/components/headers/WwwAuthenticate"
              }
            }
          },
          "403": {
            "description": "The API key cannot perform this operation: key_scope_mismatch, key_read_only or ip_not_allowed; or its account is suspended (account_suspended).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "not_found",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "409": {
            "description": "webhook_delivery_in_progress, webhook_endpoint_disabled or webhook_endpoint_not_verified. Or idempotency_key_in_progress: a request with this Idempotency-Key is still running.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "422": {
            "description": "idempotency_key_reused: the Idempotency-Key was used with a different request.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "apiKey": []
          }
        ],
        "summary": "Replay a webhook delivery",
        "tags": [
          "Webhooks"
        ]
      }
    },
    "/v1/events": {
      "get": {
        "description": "Newest first; the same objects the webhooks deliver. Any API key can read the events of its mode; an issuer-scoped key only those of its issuer.",
        "operationId": "eventsList",
        "parameters": [
          {
            "name": "limit",
            "required": false,
            "in": "query",
            "description": "Maximum number of items to return.",
            "schema": {
              "minimum": 1,
              "maximum": 100,
              "default": 20,
              "type": "integer"
            }
          },
          {
            "name": "cursor",
            "required": false,
            "in": "query",
            "description": "The `pagination.nextCursor` of the previous page. Omit it for the first page.",
            "schema": {
              "maxLength": 200,
              "type": "string"
            }
          },
          {
            "name": "type",
            "required": false,
            "in": "query",
            "description": "Only events of this type.",
            "schema": {
              "type": "string",
              "enum": [
                "invoice.authorized",
                "invoice.rejected",
                "purchase_settlement.authorized",
                "purchase_settlement.rejected",
                "credit_note.authorized",
                "credit_note.rejected",
                "debit_note.authorized",
                "debit_note.rejected",
                "waybill.authorized",
                "waybill.rejected",
                "withholding.authorized",
                "withholding.rejected",
                "certificate.verified",
                "certificate.pending",
                "certificate.blocked",
                "certificate.revoked",
                "certificate.reactivated",
                "document.ride.generated",
                "document.ride.failed",
                "document.email.sent",
                "document.email.delivered",
                "document.email.bounced",
                "document.email.complained",
                "document.email.failed",
                "account.email_paused",
                "account.email_resumed"
              ]
            }
          },
          {
            "name": "issuerId",
            "required": false,
            "in": "query",
            "description": "Only events of this issuer.",
            "schema": {
              "format": "uuid",
              "type": "string"
            }
          },
          {
            "name": "documentId",
            "required": false,
            "in": "query",
            "description": "Only events of this document.",
            "schema": {
              "format": "uuid",
              "type": "string"
            }
          },
          {
            "name": "certificateId",
            "required": false,
            "in": "query",
            "description": "Only events of this certificate.",
            "schema": {
              "format": "uuid",
              "type": "string"
            }
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          },
          {
            "$ref": "#/components/parameters/CorrelationId"
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/EventList"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/RequestId"
              }
            }
          },
          "401": {
            "description": "`authentication_required`: no `Authorization: Bearer` header. `invalid_api_key`: the key is malformed, unknown or revoked.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            },
            "headers": {
              "WWW-Authenticate": {
                "$ref": "#/components/headers/WwwAuthenticate"
              }
            }
          },
          "403": {
            "description": "The API key cannot perform this operation: key_scope_mismatch, key_read_only or ip_not_allowed; or its account is suspended (account_suspended).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "422": {
            "description": "validation_failed: invalid filter, limit or cursor.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "apiKey": []
          }
        ],
        "summary": "List events",
        "tags": [
          "Events"
        ]
      }
    },
    "/v1/events/{eventId}": {
      "get": {
        "description": "The event with its snapshot (thin webhook endpoints read it here). Any API key can read the events of its mode; an issuer-scoped key only those of its issuer.",
        "operationId": "eventsGet",
        "parameters": [
          {
            "name": "eventId",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          },
          {
            "$ref": "#/components/parameters/CorrelationId"
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Event"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/RequestId"
              }
            }
          },
          "401": {
            "description": "`authentication_required`: no `Authorization: Bearer` header. `invalid_api_key`: the key is malformed, unknown or revoked.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            },
            "headers": {
              "WWW-Authenticate": {
                "$ref": "#/components/headers/WwwAuthenticate"
              }
            }
          },
          "403": {
            "description": "The API key cannot perform this operation: key_scope_mismatch, key_read_only or ip_not_allowed; or its account is suspended (account_suspended).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "not_found",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "apiKey": []
          }
        ],
        "summary": "Get an event",
        "tags": [
          "Events"
        ]
      }
    }
  },
  "info": {
    "title": "Flashpi Invoicing API",
    "description": "Issue and query electronic tax documents authorized by Ecuador's SRI. Authenticate with an API key as a Bearer token: fp_test_ keys use the SRI test environment and fp_live_ keys use SRI production. Errors follow RFC 9457 (application/problem+json), in Spanish with Accept-Language: es. Any operation can also answer 500 internal_error (unexpected: retry with backoff, reusing the Idempotency-Key on a POST, and give requestId to support); 502, 503 and 504 answers from the edge may carry no Problem Details body. Every response carries an X-Request-Id header (a UUIDv7, also returned as requestId in errors). Send an optional X-Correlation-Id header (1 to 128 letters, digits and -_.:/+=) to tie a request to your own records: it is echoed back, and an invalid value is rejected with 400 invalid_correlation_id. JSON bodies are limited to 1 MB; a larger body gets 413 payload_too_large.",
    "version": "0.0.0",
    "contact": {}
  },
  "tags": [
    {
      "name": "Status"
    },
    {
      "name": "Issuers"
    },
    {
      "name": "Certificates"
    },
    {
      "name": "Issuer onboardings"
    },
    {
      "name": "Invoices"
    },
    {
      "name": "Credit notes"
    },
    {
      "name": "Debit notes"
    },
    {
      "name": "Purchase settlements"
    },
    {
      "name": "Waybills"
    },
    {
      "name": "Withholdings"
    },
    {
      "name": "Documents"
    },
    {
      "name": "Webhooks"
    },
    {
      "name": "Events"
    }
  ],
  "servers": [
    {
      "url": "https://api.flashpi.com.ec",
      "description": "Production (test and live keys)"
    }
  ],
  "components": {
    "securitySchemes": {
      "apiKey": {
        "scheme": "bearer",
        "bearerFormat": "fp_test_... | fp_live_...",
        "type": "http",
        "description": "Flashpi API key."
      }
    },
    "schemas": {
      "Status": {
        "type": "object",
        "properties": {
          "status": {
            "type": "string",
            "enum": [
              "operational"
            ],
            "example": "operational",
            "description": "Overall status of Flashpi."
          }
        },
        "description": "Public status of Flashpi. Placeholder until the status monitors exist.",
        "required": [
          "status"
        ]
      },
      "ErrorCode": {
        "type": "string",
        "enum": [
          "bad_request",
          "malformed_json",
          "invalid_correlation_id",
          "validation_failed",
          "authentication_required",
          "forbidden",
          "not_found",
          "method_not_allowed",
          "not_acceptable",
          "conflict",
          "payload_too_large",
          "unsupported_media_type",
          "rate_limited",
          "internal_error",
          "service_unavailable",
          "invalid_api_key",
          "key_scope_mismatch",
          "key_read_only",
          "ip_not_allowed",
          "invalid_idempotency_key",
          "idempotency_key_reused",
          "idempotency_key_in_progress",
          "issuer_already_exists",
          "establishment_already_exists",
          "emission_point_already_exists",
          "resource_in_use",
          "issuer_onboarding_not_ready",
          "issuer_onboarding_expired",
          "issuer_onboarding_completed",
          "issuer_onboarding_rejected",
          "total_mismatch",
          "sequential_already_used",
          "sequentials_exhausted",
          "document_schema_invalid",
          "document_too_large",
          "document_not_authorized",
          "ride_not_available",
          "email_recipient_missing",
          "email_already_queued",
          "email_resend_limit_reached",
          "account_email_limit_reached",
          "email_sending_paused",
          "test_recipient_not_allowed",
          "platform_email_limit_reached",
          "webhook_endpoint_disabled",
          "webhook_endpoint_already_verified",
          "webhook_endpoint_not_verified",
          "webhook_delivery_in_progress",
          "sandbox_not_enabled",
          "demo_issuer_quota_exceeded",
          "demo_issuer_unavailable",
          "account_suspended"
        ],
        "description": "Stable machine-readable error code, the same in every language. Branch on it, never on `type`, `title` or `detail`. New codes may be added: handle an unknown one by its HTTP status."
      },
      "FieldErrorCode": {
        "type": "string",
        "enum": [
          "required",
          "unknown_field",
          "invalid_type",
          "invalid_format",
          "invalid_option",
          "too_short",
          "too_long",
          "out_of_range",
          "invalid_value",
          "unsupported_character",
          "not_found",
          "invalid_decimal",
          "invalid_identification",
          "invalid_check_digit",
          "final_consumer_not_allowed",
          "not_in_force",
          "too_many_additional_fields",
          "reserved_name",
          "amount_mismatch",
          "future_date",
          "date_too_early",
          "date_too_late",
          "discount_exceeds_amount",
          "duplicate",
          "vat_required",
          "unsupported_tax",
          "rate_mismatch",
          "incompatible_issuer_profile",
          "url_not_allowed",
          "demo_issuer_test_only",
          "demo_issuer_sequential_not_allowed",
          "ruc_mismatch"
        ],
        "description": "Stable machine-readable reason. New codes may be added: treat an unknown one like `invalid_value`."
      },
      "FieldError": {
        "type": "object",
        "properties": {
          "field": {
            "type": "string",
            "example": "customer.id",
            "description": "Path of the invalid field."
          },
          "code": {
            "example": "required",
            "description": "Stable machine-readable reason. New codes may be added: treat an unknown one like `invalid_value`.",
            "allOf": [
              {
                "$ref": "#/components/schemas/FieldErrorCode"
              }
            ]
          },
          "message": {
            "type": "string",
            "example": "This field is required.",
            "description": "Localized message."
          }
        },
        "required": [
          "field",
          "code",
          "message"
        ]
      },
      "ProblemDetails": {
        "type": "object",
        "properties": {
          "type": {
            "type": "string",
            "format": "uri",
            "example": "https://flashpi.com.ec/docs/en/errors/validation_failed",
            "description": "URI of the problem type: the page that documents `code`, in the language of the response (`https://flashpi.com.ec/docs/en/errors/{code}` in English, `https://flashpi.com.ec/docs/errors/{code}` with Accept-Language: es). It changes with the language, so branch on `code`, never on `type`."
          },
          "title": {
            "type": "string",
            "example": "Validation failed",
            "description": "Localized summary of the type."
          },
          "status": {
            "type": "number",
            "example": 422,
            "description": "HTTP status code."
          },
          "detail": {
            "type": "string",
            "example": "One or more fields are invalid. See errors for details.",
            "description": "Localized explanation of this occurrence."
          },
          "instance": {
            "type": "string",
            "example": "/v1/invoices",
            "description": "Path of the request."
          },
          "code": {
            "example": "validation_failed",
            "description": "Stable machine-readable error code, the same in every language. Branch on it, never on `type`, `title` or `detail`. New codes may be added: handle an unknown one by its HTTP status.",
            "allOf": [
              {
                "$ref": "#/components/schemas/ErrorCode"
              }
            ]
          },
          "errors": {
            "description": "Field-level errors (may be empty).",
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/FieldError"
            }
          },
          "requestId": {
            "type": "string",
            "example": "017f22e2-79b0-7cc3-98c4-dc0c0c07398f",
            "description": "Request ID (UUIDv7); include it when contacting support."
          },
          "documentId": {
            "type": "string",
            "format": "uuid",
            "description": "`idempotency_key_reused`: the document the Idempotency-Key already created."
          },
          "limit": {
            "type": "integer",
            "description": "The daily limit that was reached (`email_resend_limit_reached`, `account_email_limit_reached`, `demo_issuer_quota_exceeded`)."
          },
          "resetsAt": {
            "type": "string",
            "format": "date-time",
            "description": "When the daily limit resets: the next midnight in Ecuador (the three codes above and `platform_email_limit_reached`). Retry-After gives the same in seconds."
          },
          "rideStatus": {
            "type": "string",
            "enum": [
              "pending",
              "generated",
              "failed"
            ],
            "description": "`ride_not_available`: the status of the RIDE."
          },
          "documentStatus": {
            "type": "string",
            "enum": [
              "processing",
              "pending_sri",
              "authorized",
              "rejected",
              "failed",
              "voided"
            ],
            "description": "`document_not_authorized`: the status of the document."
          },
          "environment": {
            "type": "string",
            "enum": [
              "test",
              "live"
            ],
            "description": "`email_sending_paused`: the mode whose email sending is paused."
          },
          "expectedTotal": {
            "type": "string",
            "example": "112.00",
            "description": "`total_mismatch`: the `expectedTotal` you sent."
          },
          "computedTotal": {
            "type": "string",
            "example": "111.99",
            "description": "`total_mismatch`: the total Flashpi computed."
          }
        },
        "description": "RFC 9457 problem details, in the language of Content-Language (`en`, or `es` with Accept-Language: es). Some codes add extension members, listed below; others may appear.",
        "required": [
          "type",
          "title",
          "status",
          "detail",
          "instance",
          "code",
          "errors",
          "requestId"
        ],
        "additionalProperties": true
      },
      "IssuerTaxProfileInput": {
        "type": "object",
        "properties": {
          "keepsAccounting": {
            "type": "boolean",
            "description": "Whether the taxpayer is required to keep accounting (obligado a llevar contabilidad)."
          },
          "specialTaxpayerNumber": {
            "type": [
              "string",
              "null"
            ],
            "pattern": "^[A-Za-z0-9]{3,13}$",
            "example": "5368",
            "description": "Special taxpayer (contribuyente especial) resolution number: 3 to 13 letters or digits."
          },
          "withholdingAgentResolution": {
            "type": [
              "string",
              "null"
            ],
            "pattern": "^[0-9]+$",
            "example": "1",
            "description": "Withholding agent (agente de retención) designation resolution number, digits only. Stored without leading zeros (at most 8 digits)."
          },
          "rimpeRegime": {
            "type": [
              "string",
              "null"
            ],
            "enum": [
              "entrepreneur",
              "popular_business",
              null
            ],
            "description": "RIMPE regime: `entrepreneur` (CONTRIBUYENTE RÉGIMEN RIMPE) or `popular_business` (CONTRIBUYENTE NEGOCIO POPULAR - RÉGIMEN RIMPE). Null when not in RIMPE."
          },
          "largeTaxpayerResolution": {
            "type": [
              "string",
              "null"
            ],
            "minLength": 1,
            "maxLength": 300,
            "example": "NAC-GCFOIOC21-00000868-E",
            "description": "Large taxpayer (gran contribuyente) designation resolution number."
          }
        },
        "required": [
          "keepsAccounting"
        ]
      },
      "IssuerBrandingInput": {
        "type": "object",
        "properties": {
          "brandColor": {
            "type": [
              "string",
              "null"
            ],
            "pattern": "^#[0-9A-Fa-f]{6}$",
            "example": "#0f766e",
            "description": "Brand color of the RIDE PDF, #RRGGBB (returned in lowercase)."
          }
        }
      },
      "CreateIssuer": {
        "type": "object",
        "properties": {
          "ruc": {
            "type": "string",
            "pattern": "^[0-9]{10}001$",
            "example": "1790000000001",
            "description": "RUC: 13 digits ending in 001. Only the format is checked: newer RUCs fail the modulo-11 check digit, so it is never verified. It cannot be changed later."
          },
          "legalName": {
            "type": "string",
            "minLength": 1,
            "maxLength": 300,
            "example": "Supermercados La Pradera S.A.",
            "description": "Legal name (razón social) as registered in the RUC."
          },
          "tradeName": {
            "type": [
              "string",
              "null"
            ],
            "minLength": 1,
            "maxLength": 300,
            "example": "La Pradera",
            "description": "Trade name (nombre comercial)."
          },
          "headOfficeAddress": {
            "type": "string",
            "minLength": 1,
            "maxLength": 300,
            "example": "Av. Amazonas N34-12 y Av. Atahualpa, Quito",
            "description": "Head office address (dirección matriz)."
          },
          "taxProfile": {
            "$ref": "#/components/schemas/IssuerTaxProfileInput"
          },
          "branding": {
            "$ref": "#/components/schemas/IssuerBrandingInput"
          },
          "sendEmailByDefault": {
            "type": "boolean",
            "example": true,
            "description": "Default of a document request's `options.sendEmail`: true emails every authorized document (RIDE PDF and XML) to its buyer, false opts the issuer out. A request that sets `options.sendEmail` decides for itself.",
            "default": true
          }
        },
        "required": [
          "ruc",
          "legalName",
          "headOfficeAddress",
          "taxProfile"
        ]
      },
      "IssuerTaxProfile": {
        "type": "object",
        "properties": {
          "keepsAccounting": {
            "type": "boolean",
            "description": "Whether the taxpayer is required to keep accounting (obligado a llevar contabilidad)."
          },
          "specialTaxpayerNumber": {
            "type": [
              "string",
              "null"
            ],
            "pattern": "^[A-Za-z0-9]{3,13}$",
            "example": "5368",
            "description": "Special taxpayer (contribuyente especial) resolution number: 3 to 13 letters or digits."
          },
          "withholdingAgentResolution": {
            "type": [
              "string",
              "null"
            ],
            "pattern": "^[0-9]+$",
            "example": "1",
            "description": "Withholding agent (agente de retención) designation resolution number, digits only. Stored without leading zeros (at most 8 digits)."
          },
          "rimpeRegime": {
            "type": [
              "string",
              "null"
            ],
            "enum": [
              "entrepreneur",
              "popular_business",
              null
            ],
            "description": "RIMPE regime: `entrepreneur` (CONTRIBUYENTE RÉGIMEN RIMPE) or `popular_business` (CONTRIBUYENTE NEGOCIO POPULAR - RÉGIMEN RIMPE). Null when not in RIMPE."
          },
          "largeTaxpayerResolution": {
            "type": [
              "string",
              "null"
            ],
            "minLength": 1,
            "maxLength": 300,
            "example": "NAC-GCFOIOC21-00000868-E",
            "description": "Large taxpayer (gran contribuyente) designation resolution number."
          }
        },
        "description": "Tax profile; Flashpi adds the mandatory tags and legends from it.",
        "required": [
          "keepsAccounting",
          "specialTaxpayerNumber",
          "withholdingAgentResolution",
          "rimpeRegime",
          "largeTaxpayerResolution"
        ]
      },
      "IssuerBranding": {
        "type": "object",
        "properties": {
          "brandColor": {
            "type": [
              "string",
              "null"
            ],
            "pattern": "^#[0-9A-Fa-f]{6}$",
            "example": "#0f766e",
            "description": "Brand color of the RIDE PDF, #RRGGBB (returned in lowercase)."
          }
        },
        "description": "RIDE branding of the issuer.",
        "required": [
          "brandColor"
        ]
      },
      "Issuer": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid",
            "example": "01a13eca-2e80-7c3d-9f21-5b8e4a6d0c17"
          },
          "ruc": {
            "type": "string",
            "pattern": "^[0-9]{10}001$",
            "example": "1790000000001",
            "description": "RUC: 13 digits ending in 001 (format only; the check digit is not verified)."
          },
          "legalName": {
            "type": "string",
            "minLength": 1,
            "maxLength": 300,
            "example": "Supermercados La Pradera S.A.",
            "description": "Legal name (razón social) as registered in the RUC."
          },
          "tradeName": {
            "type": [
              "string",
              "null"
            ],
            "minLength": 1,
            "maxLength": 300,
            "example": "La Pradera",
            "description": "Trade name (nombre comercial)."
          },
          "headOfficeAddress": {
            "type": "string",
            "minLength": 1,
            "maxLength": 300,
            "example": "Av. Amazonas N34-12 y Av. Atahualpa, Quito",
            "description": "Head office address (dirección matriz)."
          },
          "taxProfile": {
            "$ref": "#/components/schemas/IssuerTaxProfile"
          },
          "branding": {
            "$ref": "#/components/schemas/IssuerBranding"
          },
          "sendEmailByDefault": {
            "type": "boolean",
            "example": true,
            "description": "Default of a document request's `options.sendEmail`: true emails every authorized document (RIDE PDF and XML) to its buyer, false opts the issuer out. A request that sets `options.sendEmail` decides for itself."
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          },
          "updatedAt": {
            "type": "string",
            "format": "date-time"
          }
        },
        "description": "A taxpayer (RUC) that issues documents.",
        "required": [
          "id",
          "ruc",
          "legalName",
          "tradeName",
          "headOfficeAddress",
          "taxProfile",
          "branding",
          "sendEmailByDefault",
          "createdAt",
          "updatedAt"
        ]
      },
      "Pagination": {
        "type": "object",
        "properties": {
          "nextCursor": {
            "type": [
              "string",
              "null"
            ],
            "description": "Cursor of the next page (send it as `cursor`), or null on the last page."
          },
          "hasMore": {
            "type": "boolean",
            "description": "Whether there are more items after this page."
          }
        },
        "description": "Position of a page in a list.",
        "required": [
          "nextCursor",
          "hasMore"
        ]
      },
      "IssuerList": {
        "type": "object",
        "properties": {
          "data": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Issuer"
            }
          },
          "pagination": {
            "$ref": "#/components/schemas/Pagination"
          }
        },
        "description": "A page of issuers, newest first.",
        "required": [
          "data",
          "pagination"
        ]
      },
      "IssuerTaxProfilePatch": {
        "type": "object",
        "properties": {
          "keepsAccounting": {
            "type": "boolean",
            "description": "Whether the taxpayer is required to keep accounting (obligado a llevar contabilidad)."
          },
          "specialTaxpayerNumber": {
            "type": [
              "string",
              "null"
            ],
            "pattern": "^[A-Za-z0-9]{3,13}$",
            "example": "5368",
            "description": "Special taxpayer (contribuyente especial) resolution number: 3 to 13 letters or digits."
          },
          "withholdingAgentResolution": {
            "type": [
              "string",
              "null"
            ],
            "pattern": "^[0-9]+$",
            "example": "1",
            "description": "Withholding agent (agente de retención) designation resolution number, digits only. Stored without leading zeros (at most 8 digits)."
          },
          "rimpeRegime": {
            "type": [
              "string",
              "null"
            ],
            "enum": [
              "entrepreneur",
              "popular_business",
              null
            ],
            "description": "RIMPE regime: `entrepreneur` (CONTRIBUYENTE RÉGIMEN RIMPE) or `popular_business` (CONTRIBUYENTE NEGOCIO POPULAR - RÉGIMEN RIMPE). Null when not in RIMPE."
          },
          "largeTaxpayerResolution": {
            "type": [
              "string",
              "null"
            ],
            "minLength": 1,
            "maxLength": 300,
            "example": "NAC-GCFOIOC21-00000868-E",
            "description": "Large taxpayer (gran contribuyente) designation resolution number."
          }
        },
        "description": "Fields to change; null clears one."
      },
      "UpdateIssuer": {
        "type": "object",
        "properties": {
          "legalName": {
            "type": "string",
            "minLength": 1,
            "maxLength": 300,
            "example": "Supermercados La Pradera S.A.",
            "description": "Legal name (razón social) as registered in the RUC."
          },
          "tradeName": {
            "type": [
              "string",
              "null"
            ],
            "minLength": 1,
            "maxLength": 300,
            "example": "La Pradera",
            "description": "Trade name (nombre comercial)."
          },
          "headOfficeAddress": {
            "type": "string",
            "minLength": 1,
            "maxLength": 300,
            "example": "Av. Amazonas N34-12 y Av. Atahualpa, Quito",
            "description": "Head office address (dirección matriz)."
          },
          "taxProfile": {
            "$ref": "#/components/schemas/IssuerTaxProfilePatch"
          },
          "branding": {
            "$ref": "#/components/schemas/IssuerBrandingInput"
          },
          "sendEmailByDefault": {
            "type": "boolean",
            "example": true,
            "description": "Default of a document request's `options.sendEmail`: true emails every authorized document (RIDE PDF and XML) to its buyer, false opts the issuer out. A request that sets `options.sendEmail` decides for itself."
          }
        },
        "description": "Fields to change; null clears an optional field. The RUC cannot be changed."
      },
      "CreateEstablishment": {
        "type": "object",
        "properties": {
          "code": {
            "type": "string",
            "pattern": "^\\d{3}$",
            "example": "001",
            "description": "Establishment code (estab), 3 digits, as registered in the RUC. It cannot be changed later."
          },
          "address": {
            "type": "string",
            "minLength": 1,
            "maxLength": 300,
            "example": "Av. 9 de Octubre 1234 y Malecón, Guayaquil",
            "description": "Address of the establishment (dirección del establecimiento)."
          }
        },
        "required": [
          "code",
          "address"
        ]
      },
      "Establishment": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "issuerId": {
            "type": "string",
            "format": "uuid"
          },
          "code": {
            "type": "string",
            "pattern": "^\\d{3}$",
            "example": "001",
            "description": "Establishment code (estab), 3 digits."
          },
          "address": {
            "type": "string",
            "minLength": 1,
            "maxLength": 300,
            "example": "Av. 9 de Octubre 1234 y Malecón, Guayaquil",
            "description": "Address of the establishment (dirección del establecimiento)."
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          },
          "updatedAt": {
            "type": "string",
            "format": "date-time"
          }
        },
        "description": "An establishment of an issuer.",
        "required": [
          "id",
          "issuerId",
          "code",
          "address",
          "createdAt",
          "updatedAt"
        ]
      },
      "EstablishmentList": {
        "type": "object",
        "properties": {
          "data": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Establishment"
            }
          },
          "pagination": {
            "$ref": "#/components/schemas/Pagination"
          }
        },
        "description": "A page of establishments, by code.",
        "required": [
          "data",
          "pagination"
        ]
      },
      "UpdateEstablishment": {
        "type": "object",
        "properties": {
          "address": {
            "type": "string",
            "minLength": 1,
            "maxLength": 300,
            "example": "Av. 9 de Octubre 1234 y Malecón, Guayaquil",
            "description": "Address of the establishment (dirección del establecimiento)."
          }
        },
        "description": "Fields to change. The code cannot be changed."
      },
      "CreateEmissionPoint": {
        "type": "object",
        "properties": {
          "code": {
            "type": "string",
            "pattern": "^\\d{3}$",
            "example": "001",
            "description": "Emission point code (punto de emisión), 3 digits. It cannot be changed later."
          }
        },
        "required": [
          "code"
        ]
      },
      "EmissionPoint": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "issuerId": {
            "type": "string",
            "format": "uuid"
          },
          "establishmentId": {
            "type": "string",
            "format": "uuid"
          },
          "code": {
            "type": "string",
            "pattern": "^\\d{3}$",
            "example": "001",
            "description": "Emission point code (punto de emisión), 3 digits."
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          },
          "updatedAt": {
            "type": "string",
            "format": "date-time"
          }
        },
        "description": "An emission point of an establishment.",
        "required": [
          "id",
          "issuerId",
          "establishmentId",
          "code",
          "createdAt",
          "updatedAt"
        ]
      },
      "EmissionPointList": {
        "type": "object",
        "properties": {
          "data": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/EmissionPoint"
            }
          },
          "pagination": {
            "$ref": "#/components/schemas/Pagination"
          }
        },
        "description": "A page of emission points, by code.",
        "required": [
          "data",
          "pagination"
        ]
      },
      "CertificateRevocation": {
        "type": "object",
        "properties": {
          "status": {
            "type": "string",
            "enum": [
              "good",
              "pending",
              "blocked",
              "revoked"
            ],
            "example": "good"
          },
          "checkedAt": {
            "type": "string",
            "format": "date-time"
          },
          "nextCheckAt": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          },
          "blockAt": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time",
            "description": "Pending only: when it stops signing if still unverified."
          },
          "blockedReason": {
            "type": [
              "string",
              "null"
            ],
            "enum": [
              "revocation_status_unverified",
              "untrusted_certificate_chain",
              null
            ]
          }
        },
        "description": "Whether the certification authority revoked the certificate. `good`: verified not revoked. `pending`: could not be verified yet; it still signs until `blockAt` and is checked again hourly. `blocked`: still unverified after 7 days, or its chain is no longer trusted (`blockedReason`); it does not sign. `revoked`: never signs again.",
        "required": [
          "status",
          "checkedAt",
          "nextCheckAt",
          "blockAt",
          "blockedReason"
        ]
      },
      "CertificateRejection": {
        "type": "object",
        "properties": {
          "code": {
            "type": "string",
            "example": "invalid_password"
          },
          "message": {
            "type": "string",
            "example": "The password does not open the .p12 file."
          }
        },
        "description": "Why the upload was rejected.",
        "required": [
          "code",
          "message"
        ]
      },
      "Certificate": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "issuerId": {
            "type": "string",
            "format": "uuid"
          },
          "environment": {
            "type": "string",
            "enum": [
              "test",
              "live"
            ],
            "description": "Mode of the API key that uploaded it. A certificate of the issuer onboarding serves every mode (`allModes`): it shows the mode of the API key that reads it."
          },
          "allModes": {
            "type": "boolean",
            "description": "Whether it serves every mode (test and live): a certificate uploaded through the issuer onboarding (POST /v1/issuer-onboardings). False for one uploaded for one mode."
          },
          "status": {
            "type": "string",
            "enum": [
              "processing",
              "accepted",
              "rejected"
            ],
            "example": "processing"
          },
          "usable": {
            "type": "boolean",
            "description": "Whether it signs documents now: accepted, within its validity and not blocked."
          },
          "subject": {
            "type": [
              "string",
              "null"
            ],
            "description": "Subject distinguished name."
          },
          "issuedBy": {
            "type": [
              "string",
              "null"
            ],
            "description": "Distinguished name of the certification authority that issued it."
          },
          "serialNumber": {
            "type": [
              "string",
              "null"
            ],
            "example": "4f2a9c01"
          },
          "validFrom": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          },
          "validUntil": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          },
          "sha256Fingerprint": {
            "type": [
              "string",
              "null"
            ],
            "description": "SHA-256 of the certificate, hex."
          },
          "ruc": {
            "type": [
              "string",
              "null"
            ],
            "example": "1790000000001",
            "description": "The RUC found in the certificate, when its authority writes one."
          },
          "revocation": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/CertificateRevocation"
              },
              {
                "type": "null"
              }
            ]
          },
          "rejection": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/CertificateRejection"
              },
              {
                "type": "null"
              }
            ]
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          },
          "updatedAt": {
            "type": "string",
            "format": "date-time"
          }
        },
        "description": "An issuer's .p12 signing certificate. Flashpi checks the upload asynchronously (`processing`, then `accepted` or `rejected`); the file and its password are never returned.",
        "required": [
          "id",
          "issuerId",
          "environment",
          "allModes",
          "status",
          "usable",
          "subject",
          "issuedBy",
          "serialNumber",
          "validFrom",
          "validUntil",
          "sha256Fingerprint",
          "ruc",
          "revocation",
          "rejection",
          "createdAt",
          "updatedAt"
        ]
      },
      "CertificateList": {
        "type": "object",
        "properties": {
          "data": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Certificate"
            }
          },
          "pagination": {
            "$ref": "#/components/schemas/Pagination"
          }
        },
        "description": "A page of certificates, newest first.",
        "required": [
          "data",
          "pagination"
        ]
      },
      "IssuerOnboardingRejection": {
        "type": "object",
        "properties": {
          "code": {
            "type": "string",
            "example": "invalid_password"
          },
          "message": {
            "type": "string",
            "example": "The password does not open the .p12 file.",
            "description": "In the language of Accept-Language (Spanish or English)."
          }
        },
        "description": "Why the certificate was rejected (the certificate rejection codes).",
        "required": [
          "code",
          "message"
        ]
      },
      "IssuerOnboardingIssuingCa": {
        "type": "object",
        "properties": {
          "code": {
            "type": [
              "string",
              "null"
            ],
            "example": "SECURITY_DATA"
          },
          "displayName": {
            "type": [
              "string",
              "null"
            ],
            "example": "Security Data"
          }
        },
        "description": "The Ecuadorian certification authority that issued the certificate.",
        "required": [
          "code",
          "displayName"
        ]
      },
      "IssuerOnboardingHolder": {
        "type": "object",
        "properties": {
          "commonName": {
            "type": [
              "string",
              "null"
            ],
            "example": "JUAN CARLOS PEREZ LOPEZ",
            "description": "Common name (CN): the holder's name."
          },
          "organization": {
            "type": [
              "string",
              "null"
            ],
            "example": "SUPERMERCADOS LA PRADERA S.A.",
            "description": "Organization (O): usually the company of a legal representative."
          }
        },
        "description": "The certificate holder's names.",
        "required": [
          "commonName",
          "organization"
        ]
      },
      "IssuerOnboardingIdentification": {
        "type": "object",
        "properties": {
          "ruc": {
            "type": [
              "string",
              "null"
            ],
            "example": "1790012345001"
          },
          "rucSource": {
            "type": [
              "string",
              "null"
            ],
            "enum": [
              "certificate",
              "cedula",
              null
            ]
          },
          "cedula": {
            "type": [
              "string",
              "null"
            ],
            "example": "1712345678"
          }
        },
        "description": "The identification the certificate carries: its RUC (`rucSource` certificate), or the holder's cédula, from which Flashpi proposes the RUC cédula + 001 (`rucSource` cedula).",
        "required": [
          "ruc",
          "rucSource",
          "cedula"
        ]
      },
      "IssuerOnboardingCertificate": {
        "type": "object",
        "properties": {
          "serialNumber": {
            "type": "string",
            "example": "4f2a9c01"
          },
          "validFrom": {
            "type": "string",
            "format": "date-time"
          },
          "validTo": {
            "type": "string",
            "format": "date-time"
          },
          "issuingCa": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/IssuerOnboardingIssuingCa"
              },
              {
                "type": "null"
              }
            ]
          },
          "holder": {
            "$ref": "#/components/schemas/IssuerOnboardingHolder"
          },
          "identification": {
            "$ref": "#/components/schemas/IssuerOnboardingIdentification"
          }
        },
        "description": "Public facts of the verified certificate (no key material).",
        "required": [
          "serialNumber",
          "validFrom",
          "validTo",
          "issuingCa",
          "holder",
          "identification"
        ]
      },
      "IssuerOnboardingExistingIssuer": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "legalName": {
            "type": "string",
            "example": "Supermercados La Pradera S.A."
          }
        },
        "description": "The account's issuer that already has this RUC: completing renews its certificate instead of creating an issuer.",
        "required": [
          "id",
          "legalName"
        ]
      },
      "IssuerOnboardingSriProfile": {
        "type": "object",
        "properties": {
          "legalName": {
            "type": [
              "string",
              "null"
            ],
            "description": "Razón social."
          },
          "tradeName": {
            "type": [
              "string",
              "null"
            ],
            "description": "Nombre comercial."
          },
          "taxpayerStatus": {
            "type": [
              "string",
              "null"
            ],
            "example": "ACTIVO",
            "description": "The RUC status as the SRI writes it."
          },
          "keepsAccounting": {
            "type": [
              "boolean",
              "null"
            ]
          },
          "specialTaxpayer": {
            "type": [
              "boolean",
              "null"
            ]
          },
          "withholdingAgent": {
            "type": [
              "boolean",
              "null"
            ]
          },
          "rimpeRegime": {
            "type": "string",
            "enum": [
              "entrepreneur",
              "popular_business",
              "general",
              "unknown"
            ],
            "description": "`general`: not in RIMPE. `unknown`: the SRI answer could not be mapped; the customer chooses."
          },
          "headOfficeAddress": {
            "type": [
              "string",
              "null"
            ],
            "description": "The head office address."
          }
        },
        "description": "The taxpayer's profile in the SRI's public RUC registry, normalized. The registry gives flags only for special taxpayer and withholding agent: the resolution numbers are the customer's to type.",
        "required": [
          "legalName",
          "tradeName",
          "taxpayerStatus",
          "keepsAccounting",
          "specialTaxpayer",
          "withholdingAgent",
          "rimpeRegime",
          "headOfficeAddress"
        ]
      },
      "IssuerOnboardingSri": {
        "type": "object",
        "properties": {
          "status": {
            "type": "string",
            "enum": [
              "found",
              "not_found",
              "unavailable",
              "disabled"
            ]
          },
          "fetchedAt": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          },
          "profile": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/IssuerOnboardingSriProfile"
              },
              {
                "type": "null"
              }
            ]
          },
          "warnings": {
            "type": "array",
            "description": "`inactive`: the RUC is not ACTIVO; `ghost` and `nonexistent_transactions`: the SRI flags the taxpayer; `head_office_closed`: its head office establishment is closed.",
            "items": {
              "type": "string",
              "enum": [
                "inactive",
                "ghost",
                "nonexistent_transactions",
                "head_office_closed"
              ]
            }
          }
        },
        "description": "What the SRI's public RUC registry said about the RUC (best effort). `unavailable`: it did not answer. `disabled`: Flashpi did not ask it (the lookup is off). In both cases `profile` is null and the customer fills in the tax profile. Warnings never block.",
        "required": [
          "status",
          "fetchedAt",
          "profile",
          "warnings"
        ]
      },
      "IssuerOnboardingPrefillTaxProfile": {
        "type": "object",
        "properties": {
          "keepsAccounting": {
            "type": [
              "boolean",
              "null"
            ]
          },
          "rimpeRegime": {
            "type": [
              "string",
              "null"
            ],
            "enum": [
              "entrepreneur",
              "popular_business",
              "general",
              null
            ],
            "description": "`general` means not in RIMPE (complete with `rimpeRegime: null`); null means unknown."
          },
          "specialTaxpayer": {
            "type": [
              "boolean",
              "null"
            ],
            "description": "The SRI says special taxpayer: ask for the resolution number."
          },
          "withholdingAgent": {
            "type": [
              "boolean",
              "null"
            ],
            "description": "The SRI says withholding agent: ask for the resolution number."
          }
        },
        "description": "The tax profile to start from; null where nothing is known.",
        "required": [
          "keepsAccounting",
          "rimpeRegime",
          "specialTaxpayer",
          "withholdingAgent"
        ]
      },
      "IssuerOnboardingPrefill": {
        "type": "object",
        "properties": {
          "ruc": {
            "type": [
              "string",
              "null"
            ],
            "example": "1790012345001"
          },
          "legalName": {
            "type": [
              "string",
              "null"
            ]
          },
          "tradeName": {
            "type": [
              "string",
              "null"
            ]
          },
          "headOfficeAddress": {
            "type": [
              "string",
              "null"
            ]
          },
          "taxProfile": {
            "$ref": "#/components/schemas/IssuerOnboardingPrefillTaxProfile"
          }
        },
        "description": "Values for the issuer's tax profile: the SRI's legal name first, else the certificate's organization (companies) or common name (persons); the trade name, the head office address and the tax profile from the SRI when it answered (`sri.status` `found`), otherwise null. They are the customer's to check and edit.",
        "required": [
          "ruc",
          "legalName",
          "tradeName",
          "headOfficeAddress",
          "taxProfile"
        ]
      },
      "IssuerOnboardingCompletion": {
        "type": "object",
        "properties": {
          "issuerId": {
            "type": "string",
            "format": "uuid"
          },
          "certificateId": {
            "type": "string",
            "format": "uuid"
          }
        },
        "description": "What completing it produced.",
        "required": [
          "issuerId",
          "certificateId"
        ]
      },
      "IssuerOnboarding": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "status": {
            "type": "string",
            "enum": [
              "verifying",
              "ready",
              "rejected",
              "completed",
              "expired"
            ],
            "example": "verifying"
          },
          "expiresAt": {
            "type": "string",
            "format": "date-time",
            "description": "When it expires unless completed."
          },
          "rejection": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/IssuerOnboardingRejection"
              },
              {
                "type": "null"
              }
            ]
          },
          "certificate": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/IssuerOnboardingCertificate"
              },
              {
                "type": "null"
              }
            ]
          },
          "proposedRuc": {
            "type": [
              "string",
              "null"
            ],
            "example": "1790012345001",
            "description": "The RUC to complete with: the certificate's, or the holder's cédula followed by 001."
          },
          "rucNeedsConfirmation": {
            "type": "boolean",
            "description": "Whether the customer must confirm (or type) the RUC: it did not come from the certificate itself. Then complete must send `ruc`."
          },
          "existingIssuer": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/IssuerOnboardingExistingIssuer"
              },
              {
                "type": "null"
              }
            ]
          },
          "sri": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/IssuerOnboardingSri"
              },
              {
                "type": "null"
              }
            ]
          },
          "prefill": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/IssuerOnboardingPrefill"
              },
              {
                "type": "null"
              }
            ]
          },
          "completed": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/IssuerOnboardingCompletion"
              },
              {
                "type": "null"
              }
            ]
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          },
          "updatedAt": {
            "type": "string",
            "format": "date-time"
          }
        },
        "description": "An issuer onboarding from a .p12: Flashpi verifies the certificate (`verifying`), then it is `ready` with the certificate's facts, the RUC and, when the registry lookup is on, the SRI's profile, or `rejected`. Completing it creates the issuer (or renews an existing one) with the certificate, which serves test and live. It `expired` if not completed within 6 days, and it is deleted 30 days after it ends.",
        "required": [
          "id",
          "status",
          "expiresAt",
          "rejection",
          "certificate",
          "proposedRuc",
          "rucNeedsConfirmation",
          "existingIssuer",
          "sri",
          "prefill",
          "completed",
          "createdAt",
          "updatedAt"
        ]
      },
      "CompleteIssuerOnboarding": {
        "type": "object",
        "properties": {
          "ruc": {
            "type": "string",
            "pattern": "^[0-9]{10}001$",
            "example": "1712345678001",
            "description": "Required when the RUC did not come from the certificate (`rucNeedsConfirmation`): the proposed RUC or another one whose first 10 digits are the holder's cédula. Otherwise it may be left out, and must be the certificate's RUC when sent (422 `ruc_mismatch`)."
          },
          "legalName": {
            "type": "string",
            "minLength": 1,
            "maxLength": 300,
            "description": "Razón social."
          },
          "tradeName": {
            "type": [
              "string",
              "null"
            ],
            "minLength": 1,
            "maxLength": 300,
            "description": "Nombre comercial."
          },
          "headOfficeAddress": {
            "type": "string",
            "minLength": 1,
            "maxLength": 300,
            "description": "Dirección matriz."
          },
          "taxProfile": {
            "$ref": "#/components/schemas/IssuerTaxProfileInput"
          },
          "branding": {
            "$ref": "#/components/schemas/IssuerBrandingInput"
          },
          "sendEmailByDefault": {
            "type": "boolean",
            "default": true,
            "description": "As in POST /v1/issuers."
          }
        },
        "description": "The issuer to create, with the same fields as POST /v1/issuers (legalName, headOfficeAddress and taxProfile are required for a new issuer). For a renewal (`existingIssuer`) the body may be `{}`: the issuer is not changed (PATCH it if needed)."
      },
      "CompletedIssuerOnboarding": {
        "type": "object",
        "properties": {
          "issuer": {
            "$ref": "#/components/schemas/Issuer"
          },
          "certificate": {
            "$ref": "#/components/schemas/Certificate"
          }
        },
        "description": "The issuer (created, with establishment 001 and emission point 001, or the existing one for a renewal) and its new certificate, `processing` until Flashpi onboards it.",
        "required": [
          "issuer",
          "certificate"
        ]
      },
      "DocumentOptions": {
        "type": "object",
        "properties": {
          "sendEmail": {
            "type": "boolean",
            "description": "Email the authorized document (PDF and XML) to the counterparty, when it has an email address. Defaults to the issuer's `sendEmailByDefault` (true unless the issuer opted out).",
            "example": true
          },
          "waitForAuthorization": {
            "type": "boolean",
            "description": "Sync mode: wait for the SRI before answering. The response is 200 with the document once it is authorized, rejected or failed, or 202 with its current status (usually `pending_sri`) when the wait ends first; the document then continues asynchronously. Defaults to false (202 at once).",
            "example": false
          },
          "waitTimeoutSeconds": {
            "type": "integer",
            "description": "Sync mode: the longest wait, in seconds, from 1 to 30. Defaults to 15. A longer wait is refused with `out_of_range`. Used only with `waitForAuthorization`.",
            "example": 15,
            "minimum": 1,
            "maximum": 30
          }
        },
        "description": "How Flashpi delivers the document once the SRI authorizes it."
      },
      "DocumentParty": {
        "type": "object",
        "properties": {
          "idType": {
            "type": "string",
            "description": "Identification type: `ruc` (13 digits ending in 001, format only), `cedula` (10 digits, check digit verified), `passport`, `final_consumer` (no identification; only invoices accept it) or `foreign_id` (issued by the tax authority of another country).",
            "example": "ruc",
            "enum": [
              "ruc",
              "cedula",
              "passport",
              "final_consumer",
              "foreign_id"
            ]
          },
          "id": {
            "type": "string",
            "description": "Identification number. Required unless `idType` is `final_consumer`, whose number is always 9999999999999.",
            "example": "1790000000001",
            "minLength": 1,
            "maxLength": 20
          },
          "name": {
            "type": "string",
            "description": "Legal name or full name. Required unless `idType` is `final_consumer` (printed as CONSUMIDOR FINAL).",
            "example": "Supermercados La Pradera S.A.",
            "minLength": 1,
            "maxLength": 300
          },
          "address": {
            "type": "string",
            "description": "Address. Credit and debit notes do not print it.",
            "example": "Av. Amazonas N34-12, Quito",
            "minLength": 1,
            "maxLength": 300
          },
          "email": {
            "type": "string",
            "description": "Where the authorized document is emailed (see `options.sendEmail`).",
            "example": "compras@example.com",
            "format": "email",
            "maxLength": 320
          }
        },
        "description": "The buyer of an invoice, credit or debit note, or the supplier of a purchase settlement.",
        "required": [
          "idType"
        ]
      },
      "DocumentTax": {
        "type": "object",
        "properties": {
          "type": {
            "type": "string",
            "description": "`vat` (IVA) or `ice` (ICE).",
            "example": "vat",
            "enum": [
              "vat",
              "ice"
            ]
          },
          "rate": {
            "type": "string",
            "example": "15",
            "description": "For `vat`, the rate: `0`, `5`, `8` (differentiated, tourism), `12`, `13`, `14`, `15`, `exempt` or `not_subject`; it must be in force on the issue date (for credit and debit notes, on the modified document issue date). For `ice`, the ad valorem percentage with up to 2 decimals (for example `75`)."
          },
          "code": {
            "type": "string",
            "description": "For `ice` only (required): the 4-digit ICE code of TABLA 18.",
            "example": "3031",
            "pattern": "^\\d{4}$"
          }
        },
        "description": "A tax of a line. Every line needs exactly one `vat`; invoices and credit notes accept one ad valorem `ice` too. Flashpi computes the bases and amounts.",
        "required": [
          "type",
          "rate"
        ]
      },
      "DocumentItem": {
        "type": "object",
        "properties": {
          "code": {
            "type": "string",
            "description": "Your product code. Required on invoices and purchase settlements.",
            "example": "SKU-001",
            "minLength": 1,
            "maxLength": 25
          },
          "auxiliaryCode": {
            "type": "string",
            "description": "A second code, for example the barcode.",
            "example": "2001234500012",
            "minLength": 1,
            "maxLength": 25
          },
          "description": {
            "type": "string",
            "description": "Description.",
            "example": "Ground coffee 500 g",
            "minLength": 1,
            "maxLength": 300
          },
          "unit": {
            "type": "string",
            "description": "Unit of measure (invoices and purchase settlements).",
            "example": "UNIT",
            "minLength": 1,
            "maxLength": 50
          },
          "quantity": {
            "type": "string",
            "description": "Quantity, up to 6 decimals.",
            "example": "2",
            "pattern": "^\\d{1,12}(\\.\\d{1,6}0*)?$"
          },
          "unitPrice": {
            "type": "string",
            "description": "Unit price without taxes, up to 6 decimals.",
            "example": "4.50",
            "pattern": "^\\d{1,12}(\\.\\d{1,6}0*)?$"
          },
          "discount": {
            "type": "string",
            "description": "Discount amount of the line (not a percentage), up to 2 decimals. Defaults to 0.",
            "example": "0.50",
            "pattern": "^\\d{1,12}(\\.\\d{1,2}0*)?$"
          },
          "taxes": {
            "description": "The taxes of the line.",
            "example": [
              {
                "type": "vat",
                "rate": "15"
              }
            ],
            "minItems": 1,
            "maxItems": 2,
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/DocumentTax"
            }
          },
          "additionalDetails": {
            "type": "object",
            "description": "Up to 3 extra details printed with the line (name → value, 1 to 300 characters).",
            "example": {
              "Batch": "L-2026-10"
            },
            "additionalProperties": {
              "type": "string",
              "minLength": 1,
              "maxLength": 300
            },
            "maxProperties": 3
          }
        },
        "description": "A line of an invoice, credit note or purchase settlement. Flashpi computes its subtotal (quantity × unit price − discount, rounded to 2 decimals) and its taxes.",
        "required": [
          "description",
          "quantity",
          "unitPrice",
          "taxes"
        ]
      },
      "DocumentPayment": {
        "type": "object",
        "properties": {
          "method": {
            "type": "string",
            "description": "Payment method: `cash` (without the financial system), `debt_offset`, `debit_card`, `electronic_money`, `prepaid_card`, `credit_card`, `other_financial_system` (bank transfers, checks and other payments through the financial system) or `securities_endorsement`.",
            "example": "credit_card",
            "enum": [
              "cash",
              "debt_offset",
              "debit_card",
              "electronic_money",
              "prepaid_card",
              "credit_card",
              "other_financial_system",
              "securities_endorsement"
            ]
          },
          "amount": {
            "type": "string",
            "description": "Amount paid with this method.",
            "example": "10.35",
            "pattern": "^\\d{1,12}(\\.\\d{1,2}0*)?$"
          },
          "term": {
            "type": "string",
            "description": "Payment term in `termUnit` units. Required on purchase settlements.",
            "example": "30",
            "pattern": "^\\d{1,12}(\\.\\d{1,2}0*)?$"
          },
          "termUnit": {
            "type": "string",
            "description": "Unit of `term`: `days` or `months`.",
            "example": "days",
            "enum": [
              "days",
              "months"
            ]
          }
        },
        "description": "A payment. The payments must add up to the document total.",
        "required": [
          "method",
          "amount"
        ]
      },
      "CreateInvoice": {
        "type": "object",
        "properties": {
          "issuerId": {
            "type": "string",
            "format": "uuid",
            "example": "01a13eca-2e80-7c3d-9f21-5b8e4a6d0c17",
            "description": "The issuer (taxpayer) that issues the document."
          },
          "establishment": {
            "type": "string",
            "description": "Establishment code (3 digits) registered on the issuer.",
            "example": "001",
            "pattern": "^\\d{3}$"
          },
          "emissionPoint": {
            "type": "string",
            "description": "Emission point code (3 digits) registered on the establishment.",
            "example": "001",
            "pattern": "^\\d{3}$"
          },
          "issueDate": {
            "type": "string",
            "description": "Issue date, YYYY-MM-DD. Defaults to today in Ecuador; it cannot be later.",
            "example": "2026-10-15",
            "format": "date"
          },
          "sequential": {
            "type": "integer",
            "description": "Sequential to use instead of the next one, for example when migrating from another system. It must not be used yet; later automatic sequentials continue after the highest one used. Not accepted with the shared demo issuer (422 demo_issuer_sequential_not_allowed).",
            "example": 1501,
            "minimum": 1,
            "maximum": 999999999
          },
          "additionalInfo": {
            "type": "object",
            "description": "Additional information printed on the document (name → value, 1 to 300 characters each). A document carries at most 15 fields including the legends Flashpi adds (RUC Proveedor, and Gran Contribuyente for large taxpayers), so at most 13 or 14 of yours.",
            "example": {
              "Order": "PO-4812"
            },
            "additionalProperties": {
              "type": "string",
              "minLength": 1,
              "maxLength": 300
            },
            "maxProperties": 15
          },
          "options": {
            "description": "Delivery options.",
            "allOf": [
              {
                "$ref": "#/components/schemas/DocumentOptions"
              }
            ]
          },
          "customer": {
            "description": "The buyer. `final_consumer` may omit `id` and `name`; the maximum amount of a final consumer invoice is not enforced yet.",
            "allOf": [
              {
                "$ref": "#/components/schemas/DocumentParty"
              }
            ]
          },
          "items": {
            "description": "The lines of the document.",
            "minItems": 1,
            "maxItems": 1000,
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/DocumentItem"
            }
          },
          "payments": {
            "description": "How the invoice is paid; the payments must add up to the total.",
            "minItems": 1,
            "maxItems": 50,
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/DocumentPayment"
            }
          },
          "tip": {
            "type": "string",
            "description": "Tip (propina). Defaults to 0.",
            "example": "1.00",
            "pattern": "^\\d{1,12}(\\.\\d{1,2}0*)?$"
          },
          "waybillNumber": {
            "type": "string",
            "description": "Number of the waybill (guía de remisión) that carried the goods.",
            "example": "001-001-000000045",
            "pattern": "^\\d{3}-\\d{3}-\\d{9}$"
          },
          "expectedTotal": {
            "type": "string",
            "description": "The total you expect. Flashpi computes every total; when it differs from this value the request is refused with 422 total_mismatch, which shows both values.",
            "example": "10.35",
            "pattern": "^\\d{1,12}(\\.\\d{1,2}0*)?$"
          }
        },
        "description": "An invoice (factura). Send quantities, prices and tax rates; Flashpi computes the line subtotals, the taxes per rate, the tip and the total with the SRI rounding rules.",
        "required": [
          "issuerId",
          "establishment",
          "emissionPoint",
          "customer",
          "items",
          "payments"
        ]
      },
      "DocumentCounterparty": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "example": "1790000000001"
          },
          "name": {
            "type": "string",
            "example": "Supermercados La Pradera S.A."
          }
        },
        "description": "The buyer, supplier, withheld subject or carrier.",
        "required": [
          "id",
          "name"
        ]
      },
      "DocumentTaxTotal": {
        "type": "object",
        "properties": {
          "type": {
            "type": "string",
            "enum": [
              "vat",
              "ice"
            ],
            "example": "vat"
          },
          "rate": {
            "type": "string",
            "example": "15",
            "description": "VAT: the rate (`15`, `0`, `exempt`, ...). ICE: the percentage."
          },
          "code": {
            "type": "string",
            "example": "3031",
            "description": "ICE: the TABLA 18 code."
          },
          "taxableBase": {
            "type": "string",
            "example": "57.50",
            "description": "Taxable base."
          },
          "amount": {
            "type": "string",
            "example": "8.63",
            "description": "Tax amount."
          }
        },
        "description": "A tax total, grouped per tax and rate.",
        "required": [
          "type",
          "rate",
          "taxableBase",
          "amount"
        ]
      },
      "DocumentTotals": {
        "type": "object",
        "properties": {
          "subtotal": {
            "type": "string",
            "example": "60.31",
            "description": "Sum of the line subtotals."
          },
          "discount": {
            "type": "string",
            "example": "0.75",
            "description": "Sum of the line discounts."
          },
          "taxes": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/DocumentTaxTotal"
            }
          },
          "tip": {
            "type": "string",
            "example": "0.00",
            "description": "Tip."
          },
          "total": {
            "type": "string",
            "example": "68.94",
            "description": "Total (credited amount of a credit note, total of a debit note)."
          },
          "withheld": {
            "type": "string",
            "example": "62.50",
            "description": "Total withheld."
          }
        },
        "description": "Totals computed by Flashpi. Invoices have every field but `withheld`; purchase settlements and credit notes have no `tip`; debit notes have no `discount` nor `tip`; withholding receipts only have `withheld`."
      },
      "DocumentAuthorization": {
        "type": "object",
        "properties": {
          "number": {
            "type": [
              "string",
              "null"
            ],
            "example": null,
            "description": "Authorization number (the access key), once authorized."
          },
          "authorizedAt": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time",
            "example": null
          }
        },
        "description": "The SRI authorization.",
        "required": [
          "number",
          "authorizedAt"
        ]
      },
      "DocumentRide": {
        "type": "object",
        "properties": {
          "status": {
            "type": "string",
            "enum": [
              "pending",
              "generated",
              "failed"
            ],
            "example": "pending"
          },
          "template": {
            "type": [
              "string",
              "null"
            ],
            "enum": [
              "modern",
              "classic",
              "minimal",
              null
            ],
            "example": null
          },
          "generatedAt": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time",
            "example": null
          }
        },
        "description": "The RIDE (printed PDF), generated once the document is authorized.",
        "required": [
          "status",
          "template",
          "generatedAt"
        ]
      },
      "DocumentEmailDelivery": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "recipient": {
            "type": "string",
            "example": "compras@example.com"
          },
          "status": {
            "type": "string",
            "enum": [
              "queued",
              "sent",
              "delivered",
              "bounced",
              "complained",
              "failed"
            ],
            "example": "delivered"
          },
          "sentAt": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          },
          "lastEventAt": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          },
          "error": {
            "type": [
              "string",
              "null"
            ],
            "example": null,
            "description": "Why the email failed or bounced, as a code: for example `rejected`, `timeout`, `invalid_address`, `bounce_permanent`, `bounce_suppressed` (the address is on the suppression list of Flashpi's email provider after an earlier bounce or complaint), `complaint`, `account_email_limit_reached` (the account's emails of the day were used up; nothing was sent), `platform_email_limit_reached` (Flashpi's emails of the day across all accounts were used up; nothing was sent), `email_sending_paused` (the account's emails of the mode are paused; nothing was sent), `platform_email_sending_paused` (Flashpi paused the emails of its email provider for every account after too many bounces or complaints; nothing was sent), `test_recipient_not_allowed` (a test document whose recipient is not a verified member of the account's team; nothing was sent: download the RIDE and the XML to send them) or `invalid_domain` (the recipient's domain does not exist or receives no mail: no MX, A or AAAA record, or a null MX; nothing was sent)."
          }
        },
        "description": "One email to one recipient.",
        "required": [
          "id",
          "recipient",
          "status",
          "sentAt",
          "lastEventAt",
          "error"
        ]
      },
      "DocumentEmailWarning": {
        "type": "object",
        "properties": {
          "code": {
            "type": "string",
            "enum": [
              "recipient_domain_typo"
            ],
            "example": "recipient_domain_typo",
            "description": "`recipient_domain_typo`: the recipient's domain looks like a typo of a common mail domain (for example gmial.com for gmail.com). The email is still sent to the address as given; nothing changes it."
          },
          "message": {
            "type": "string",
            "example": "The recipient's email address may be mistyped: did you mean compras@gmail.com?",
            "description": "Follows Accept-Language (English or Spanish)."
          },
          "suggestedRecipient": {
            "type": "string",
            "example": "compras@gmail.com",
            "description": "The address with the suggested domain."
          }
        },
        "description": "Something about the email that looks wrong. A warning never stops or changes the email.",
        "required": [
          "code",
          "message",
          "suggestedRecipient"
        ]
      },
      "DocumentEmail": {
        "type": "object",
        "properties": {
          "requested": {
            "type": "boolean",
            "example": true,
            "description": "Whether the email was requested."
          },
          "status": {
            "type": "string",
            "enum": [
              "not_requested",
              "skipped",
              "queued",
              "sent",
              "delivered",
              "bounced",
              "complained",
              "failed"
            ],
            "example": "queued",
            "description": "`not_requested` (opted out), `skipped` (no recipient), `queued` (sent once authorized), then `sent`, `delivered`, `bounced`, `complained` or `failed`."
          },
          "deliveries": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/DocumentEmailDelivery"
            }
          },
          "warnings": {
            "description": "Warnings about the recipient's address, computed when the document is read: empty when nothing looks wrong.",
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/DocumentEmailWarning"
            }
          }
        },
        "description": "Email delivery, separate from the tax status: sent only once the document is authorized, when it was requested and there is a recipient.",
        "required": [
          "requested",
          "status",
          "deliveries",
          "warnings"
        ]
      },
      "DocumentSriMessage": {
        "type": "object",
        "properties": {
          "code": {
            "type": "string",
            "example": "calculation_mismatch",
            "description": "Flashpi error code."
          },
          "message": {
            "type": "string",
            "example": "The SRI found differences in the calculations."
          },
          "severity": {
            "type": "string",
            "enum": [
              "error",
              "warning"
            ],
            "example": "error"
          }
        },
        "description": "A message of the SRI, mapped by Flashpi.",
        "required": [
          "code",
          "message",
          "severity"
        ]
      },
      "DocumentFailure": {
        "type": "object",
        "properties": {
          "code": {
            "type": "string",
            "enum": [
              "certificate_required",
              "certificate_expired",
              "certificate_not_yet_valid",
              "certificate_blocked",
              "certificate_revoked",
              "certificate_unusable",
              "document_too_large",
              "document_invalid",
              "signing_failed",
              "sri_unavailable",
              "sri_authorization_timeout",
              "sri_request_refused",
              "sri_environment_mismatch"
            ],
            "example": "certificate_required"
          },
          "message": {
            "type": "string",
            "example": "The issuer has no accepted signing certificate for this mode. Upload its .p12 certificate and issue the document again."
          }
        },
        "description": "Why a `failed` document could not reach an SRI answer.",
        "required": [
          "code",
          "message"
        ]
      },
      "Document": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid",
            "example": "01a13fdf-9620-77a7-a18e-0b13542f5fed"
          },
          "type": {
            "type": "string",
            "enum": [
              "invoice",
              "purchase_settlement",
              "credit_note",
              "debit_note",
              "waybill",
              "withholding"
            ],
            "example": "invoice"
          },
          "environment": {
            "type": "string",
            "enum": [
              "test",
              "live"
            ],
            "example": "test",
            "description": "Mode of the API key that issued it: `test` (SRI pruebas) or `live`."
          },
          "status": {
            "type": "string",
            "enum": [
              "processing",
              "pending_sri",
              "authorized",
              "rejected",
              "failed",
              "voided"
            ],
            "example": "processing",
            "description": "Tax status: `processing` (being signed and sent), `pending_sri` (waiting for the SRI), `authorized`, `rejected`, `failed` or `voided`."
          },
          "issuerId": {
            "type": "string",
            "format": "uuid"
          },
          "establishment": {
            "type": "string",
            "example": "001"
          },
          "emissionPoint": {
            "type": "string",
            "example": "001"
          },
          "sequential": {
            "type": "number",
            "example": 123
          },
          "number": {
            "type": "string",
            "example": "001-001-000000123",
            "description": "Establishment-emission point-sequential."
          },
          "accessKey": {
            "type": "string",
            "example": "1510202601179000000000110010010000001234152637411",
            "description": "The 49-digit access key, also the authorization number."
          },
          "issueDate": {
            "type": "string",
            "format": "date",
            "example": "2026-10-15"
          },
          "xmlVersion": {
            "type": "string",
            "example": "2.1.0",
            "description": "Version of the SRI XML."
          },
          "counterparty": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/DocumentCounterparty"
              },
              {
                "type": "null"
              }
            ]
          },
          "totals": {
            "description": "Null for waybills.",
            "anyOf": [
              {
                "$ref": "#/components/schemas/DocumentTotals"
              },
              {
                "type": "null"
              }
            ]
          },
          "authorization": {
            "$ref": "#/components/schemas/DocumentAuthorization"
          },
          "ride": {
            "$ref": "#/components/schemas/DocumentRide"
          },
          "email": {
            "$ref": "#/components/schemas/DocumentEmail"
          },
          "sriMessages": {
            "description": "Messages of the last SRI answer, mapped to Flashpi codes (the reasons of a rejection, or warnings of an authorization). Texts follow Accept-Language (English or Spanish).",
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/DocumentSriMessage"
            }
          },
          "failure": {
            "description": "Set when `status` is `failed`.",
            "anyOf": [
              {
                "$ref": "#/components/schemas/DocumentFailure"
              },
              {
                "type": "null"
              }
            ]
          },
          "voidedAt": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          },
          "updatedAt": {
            "type": "string",
            "format": "date-time"
          }
        },
        "description": "An SRI document of any type.",
        "required": [
          "id",
          "type",
          "environment",
          "status",
          "issuerId",
          "establishment",
          "emissionPoint",
          "sequential",
          "number",
          "accessKey",
          "issueDate",
          "xmlVersion",
          "counterparty",
          "totals",
          "authorization",
          "ride",
          "email",
          "sriMessages",
          "failure",
          "voidedAt",
          "createdAt",
          "updatedAt"
        ]
      },
      "ModifiedDocument": {
        "type": "object",
        "properties": {
          "type": {
            "type": "string",
            "description": "Type of the modified document. Defaults to `invoice`.",
            "example": "invoice",
            "enum": [
              "invoice"
            ]
          },
          "number": {
            "type": "string",
            "description": "Number of the modified document: establishment-emission point-sequential.",
            "example": "001-001-000000123",
            "pattern": "^\\d{3}-\\d{3}-\\d{9}$"
          },
          "issueDate": {
            "type": "string",
            "description": "Issue date of the modified document (on or before the note). Its VAT rates are the ones in force on this date.",
            "example": "2026-10-15",
            "format": "date"
          }
        },
        "description": "The document a credit or debit note modifies.",
        "required": [
          "number",
          "issueDate"
        ]
      },
      "CreateCreditNote": {
        "type": "object",
        "properties": {
          "issuerId": {
            "type": "string",
            "format": "uuid",
            "example": "01a13eca-2e80-7c3d-9f21-5b8e4a6d0c17",
            "description": "The issuer (taxpayer) that issues the document."
          },
          "establishment": {
            "type": "string",
            "description": "Establishment code (3 digits) registered on the issuer.",
            "example": "001",
            "pattern": "^\\d{3}$"
          },
          "emissionPoint": {
            "type": "string",
            "description": "Emission point code (3 digits) registered on the establishment.",
            "example": "001",
            "pattern": "^\\d{3}$"
          },
          "issueDate": {
            "type": "string",
            "description": "Issue date, YYYY-MM-DD. Defaults to today in Ecuador; it cannot be later.",
            "example": "2026-10-15",
            "format": "date"
          },
          "sequential": {
            "type": "integer",
            "description": "Sequential to use instead of the next one, for example when migrating from another system. It must not be used yet; later automatic sequentials continue after the highest one used. Not accepted with the shared demo issuer (422 demo_issuer_sequential_not_allowed).",
            "example": 1501,
            "minimum": 1,
            "maximum": 999999999
          },
          "additionalInfo": {
            "type": "object",
            "description": "Additional information printed on the document (name → value, 1 to 300 characters each). A document carries at most 15 fields including the legends Flashpi adds (RUC Proveedor, and Gran Contribuyente for large taxpayers), so at most 13 or 14 of yours.",
            "example": {
              "Order": "PO-4812"
            },
            "additionalProperties": {
              "type": "string",
              "minLength": 1,
              "maxLength": 300
            },
            "maxProperties": 15
          },
          "options": {
            "description": "Delivery options.",
            "allOf": [
              {
                "$ref": "#/components/schemas/DocumentOptions"
              }
            ]
          },
          "customer": {
            "description": "The buyer of the modified document. It cannot be a final consumer.",
            "allOf": [
              {
                "$ref": "#/components/schemas/DocumentParty"
              }
            ]
          },
          "modifiedDocument": {
            "description": "The document the note modifies.",
            "allOf": [
              {
                "$ref": "#/components/schemas/ModifiedDocument"
              }
            ]
          },
          "reason": {
            "type": "string",
            "description": "Reason for the note.",
            "example": "Return of damaged goods",
            "minLength": 1,
            "maxLength": 300
          },
          "items": {
            "description": "The lines of the document.",
            "minItems": 1,
            "maxItems": 1000,
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/DocumentItem"
            }
          },
          "expectedTotal": {
            "type": "string",
            "description": "The total you expect. Flashpi computes every total; when it differs from this value the request is refused with 422 total_mismatch, which shows both values.",
            "example": "10.35",
            "pattern": "^\\d{1,12}(\\.\\d{1,2}0*)?$"
          }
        },
        "description": "A credit note (nota de crédito) that reduces the amount of a document, for example for returned goods. Flashpi computes the credited amount.",
        "required": [
          "issuerId",
          "establishment",
          "emissionPoint",
          "customer",
          "modifiedDocument",
          "reason",
          "items"
        ]
      },
      "DebitNoteReason": {
        "type": "object",
        "properties": {
          "description": {
            "type": "string",
            "description": "Reason.",
            "example": "Late payment interest",
            "minLength": 1,
            "maxLength": 300
          },
          "amount": {
            "type": "string",
            "description": "Amount before taxes.",
            "example": "10.00",
            "pattern": "^\\d{1,12}(\\.\\d{1,2}0*)?$"
          },
          "taxes": {
            "description": "The VAT of this amount (exactly one `vat`).",
            "example": [
              {
                "type": "vat",
                "rate": "15"
              }
            ],
            "minItems": 1,
            "maxItems": 1,
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/DocumentTax"
            }
          }
        },
        "description": "A reason for a debit note and its amount before taxes.",
        "required": [
          "description",
          "amount",
          "taxes"
        ]
      },
      "CreateDebitNote": {
        "type": "object",
        "properties": {
          "issuerId": {
            "type": "string",
            "format": "uuid",
            "example": "01a13eca-2e80-7c3d-9f21-5b8e4a6d0c17",
            "description": "The issuer (taxpayer) that issues the document."
          },
          "establishment": {
            "type": "string",
            "description": "Establishment code (3 digits) registered on the issuer.",
            "example": "001",
            "pattern": "^\\d{3}$"
          },
          "emissionPoint": {
            "type": "string",
            "description": "Emission point code (3 digits) registered on the establishment.",
            "example": "001",
            "pattern": "^\\d{3}$"
          },
          "issueDate": {
            "type": "string",
            "description": "Issue date, YYYY-MM-DD. Defaults to today in Ecuador; it cannot be later.",
            "example": "2026-10-15",
            "format": "date"
          },
          "sequential": {
            "type": "integer",
            "description": "Sequential to use instead of the next one, for example when migrating from another system. It must not be used yet; later automatic sequentials continue after the highest one used. Not accepted with the shared demo issuer (422 demo_issuer_sequential_not_allowed).",
            "example": 1501,
            "minimum": 1,
            "maximum": 999999999
          },
          "additionalInfo": {
            "type": "object",
            "description": "Additional information printed on the document (name → value, 1 to 300 characters each). A document carries at most 15 fields including the legends Flashpi adds (RUC Proveedor, and Gran Contribuyente for large taxpayers), so at most 13 or 14 of yours.",
            "example": {
              "Order": "PO-4812"
            },
            "additionalProperties": {
              "type": "string",
              "minLength": 1,
              "maxLength": 300
            },
            "maxProperties": 15
          },
          "options": {
            "description": "Delivery options.",
            "allOf": [
              {
                "$ref": "#/components/schemas/DocumentOptions"
              }
            ]
          },
          "customer": {
            "description": "The buyer of the modified document. It cannot be a final consumer.",
            "allOf": [
              {
                "$ref": "#/components/schemas/DocumentParty"
              }
            ]
          },
          "modifiedDocument": {
            "description": "The document the note modifies.",
            "allOf": [
              {
                "$ref": "#/components/schemas/ModifiedDocument"
              }
            ]
          },
          "reasons": {
            "description": "The reasons and their amounts.",
            "minItems": 1,
            "maxItems": 100,
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/DebitNoteReason"
            }
          },
          "payments": {
            "description": "How the debit is paid; the payments must add up to the total.",
            "minItems": 1,
            "maxItems": 50,
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/DocumentPayment"
            }
          },
          "expectedTotal": {
            "type": "string",
            "description": "The total you expect. Flashpi computes every total; when it differs from this value the request is refused with 422 total_mismatch, which shows both values.",
            "example": "10.35",
            "pattern": "^\\d{1,12}(\\.\\d{1,2}0*)?$"
          }
        },
        "description": "A debit note (nota de débito) that increases the amount of a document, for example for interest or fees. Flashpi computes the taxes and the total.",
        "required": [
          "issuerId",
          "establishment",
          "emissionPoint",
          "customer",
          "modifiedDocument",
          "reasons",
          "payments"
        ]
      },
      "CreatePurchaseSettlement": {
        "type": "object",
        "properties": {
          "issuerId": {
            "type": "string",
            "format": "uuid",
            "example": "01a13eca-2e80-7c3d-9f21-5b8e4a6d0c17",
            "description": "The issuer (taxpayer) that issues the document."
          },
          "establishment": {
            "type": "string",
            "description": "Establishment code (3 digits) registered on the issuer.",
            "example": "001",
            "pattern": "^\\d{3}$"
          },
          "emissionPoint": {
            "type": "string",
            "description": "Emission point code (3 digits) registered on the establishment.",
            "example": "001",
            "pattern": "^\\d{3}$"
          },
          "issueDate": {
            "type": "string",
            "description": "Issue date, YYYY-MM-DD. Defaults to today in Ecuador; it cannot be later.",
            "example": "2026-10-15",
            "format": "date"
          },
          "sequential": {
            "type": "integer",
            "description": "Sequential to use instead of the next one, for example when migrating from another system. It must not be used yet; later automatic sequentials continue after the highest one used. Not accepted with the shared demo issuer (422 demo_issuer_sequential_not_allowed).",
            "example": 1501,
            "minimum": 1,
            "maximum": 999999999
          },
          "additionalInfo": {
            "type": "object",
            "description": "Additional information printed on the document (name → value, 1 to 300 characters each). A document carries at most 15 fields including the legends Flashpi adds (RUC Proveedor, and Gran Contribuyente for large taxpayers), so at most 13 or 14 of yours.",
            "example": {
              "Order": "PO-4812"
            },
            "additionalProperties": {
              "type": "string",
              "minLength": 1,
              "maxLength": 300
            },
            "maxProperties": 15
          },
          "options": {
            "description": "Delivery options.",
            "allOf": [
              {
                "$ref": "#/components/schemas/DocumentOptions"
              }
            ]
          },
          "supplier": {
            "description": "The supplier. It cannot be a final consumer.",
            "allOf": [
              {
                "$ref": "#/components/schemas/DocumentParty"
              }
            ]
          },
          "items": {
            "description": "The lines of the document.",
            "minItems": 1,
            "maxItems": 1000,
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/DocumentItem"
            }
          },
          "payments": {
            "description": "How the purchase is paid; the payments must add up to the total and each one needs a `term`.",
            "minItems": 1,
            "maxItems": 50,
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/DocumentPayment"
            }
          },
          "expectedTotal": {
            "type": "string",
            "description": "The total you expect. Flashpi computes every total; when it differs from this value the request is refused with 422 total_mismatch, which shows both values.",
            "example": "10.35",
            "pattern": "^\\d{1,12}(\\.\\d{1,2}0*)?$"
          }
        },
        "description": "A purchase settlement (liquidación de compra): the buyer documents a purchase from a supplier without a RUC or who cannot issue invoices. Lines take VAT only.",
        "required": [
          "issuerId",
          "establishment",
          "emissionPoint",
          "supplier",
          "items",
          "payments"
        ]
      },
      "WaybillCarrier": {
        "type": "object",
        "properties": {
          "idType": {
            "type": "string",
            "description": "Identification type of the carrier (not `final_consumer`).",
            "example": "ruc",
            "enum": [
              "ruc",
              "cedula",
              "passport",
              "final_consumer",
              "foreign_id"
            ]
          },
          "id": {
            "type": "string",
            "description": "Identification number.",
            "example": "0190000000001",
            "minLength": 1,
            "maxLength": 20
          },
          "name": {
            "type": "string",
            "description": "Legal name.",
            "example": "Transportes Andinos Cía. Ltda.",
            "minLength": 1,
            "maxLength": 300
          }
        },
        "description": "Who carries the goods.",
        "required": [
          "idType",
          "id",
          "name"
        ]
      },
      "WaybillSupportingDocument": {
        "type": "object",
        "properties": {
          "type": {
            "type": "string",
            "description": "Type of the supporting document.",
            "example": "invoice",
            "enum": [
              "invoice",
              "purchase_settlement",
              "credit_note",
              "debit_note",
              "waybill",
              "withholding"
            ]
          },
          "number": {
            "type": "string",
            "description": "Its number.",
            "example": "001-001-000001234",
            "pattern": "^\\d{3}-\\d{3}-\\d{9}$"
          },
          "authorizationNumber": {
            "type": "string",
            "description": "Its authorization number (the 49-digit access key of electronic documents).",
            "example": "1510202601179000000000110010010000012344152637411",
            "pattern": "^(\\d{10}|\\d{37}|\\d{49})$"
          },
          "issueDate": {
            "type": "string",
            "description": "Its issue date.",
            "example": "2026-10-15",
            "format": "date"
          }
        },
        "description": "The document that supports the transfer, usually the sales invoice."
      },
      "WaybillItem": {
        "type": "object",
        "properties": {
          "code": {
            "type": "string",
            "description": "Your product code.",
            "example": "SKU-001",
            "minLength": 1,
            "maxLength": 25
          },
          "auxiliaryCode": {
            "type": "string",
            "description": "A second code.",
            "example": "2001234500012",
            "minLength": 1,
            "maxLength": 25
          },
          "description": {
            "type": "string",
            "description": "Description.",
            "example": "Ground coffee 500 g",
            "minLength": 1,
            "maxLength": 300
          },
          "quantity": {
            "type": "string",
            "description": "Quantity, up to 6 decimals.",
            "example": "24",
            "pattern": "^\\d{1,12}(\\.\\d{1,6}0*)?$"
          },
          "additionalDetails": {
            "type": "object",
            "description": "Up to 3 extra details (name → value).",
            "example": {
              "Batch": "L-2026-10"
            },
            "additionalProperties": {
              "type": "string",
              "minLength": 1,
              "maxLength": 300
            },
            "maxProperties": 3
          }
        },
        "description": "Goods carried for a recipient.",
        "required": [
          "description",
          "quantity"
        ]
      },
      "WaybillRecipient": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "description": "Identification number.",
            "example": "1790000000001",
            "minLength": 1,
            "maxLength": 20
          },
          "name": {
            "type": "string",
            "description": "Legal name.",
            "example": "Supermercados La Pradera S.A.",
            "minLength": 1,
            "maxLength": 300
          },
          "address": {
            "type": "string",
            "description": "Delivery address.",
            "example": "Av. Amazonas N34-12, Quito",
            "minLength": 1,
            "maxLength": 300
          },
          "transferReason": {
            "type": "string",
            "description": "Reason for the transfer.",
            "example": "Sale",
            "minLength": 1,
            "maxLength": 300
          },
          "customsDocument": {
            "type": "string",
            "description": "Single customs document (DAU), for imports and exports.",
            "example": "0552026100000123",
            "minLength": 1,
            "maxLength": 20
          },
          "destinationEstablishment": {
            "type": "string",
            "description": "Destination establishment code of the recipient.",
            "example": "001",
            "pattern": "^\\d{3}$"
          },
          "route": {
            "type": "string",
            "description": "Route.",
            "example": "Guayaquil - Quito",
            "minLength": 1,
            "maxLength": 300
          },
          "supportingDocument": {
            "description": "The supporting document.",
            "allOf": [
              {
                "$ref": "#/components/schemas/WaybillSupportingDocument"
              }
            ]
          },
          "items": {
            "description": "The goods carried for this recipient.",
            "minItems": 1,
            "maxItems": 1000,
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/WaybillItem"
            }
          }
        },
        "description": "Who receives the goods, and what.",
        "required": [
          "id",
          "name",
          "address",
          "transferReason",
          "items"
        ]
      },
      "CreateWaybill": {
        "type": "object",
        "properties": {
          "issuerId": {
            "type": "string",
            "format": "uuid",
            "example": "01a13eca-2e80-7c3d-9f21-5b8e4a6d0c17",
            "description": "The issuer (taxpayer) that issues the document."
          },
          "establishment": {
            "type": "string",
            "description": "Establishment code (3 digits) registered on the issuer.",
            "example": "001",
            "pattern": "^\\d{3}$"
          },
          "emissionPoint": {
            "type": "string",
            "description": "Emission point code (3 digits) registered on the establishment.",
            "example": "001",
            "pattern": "^\\d{3}$"
          },
          "issueDate": {
            "type": "string",
            "description": "Issue date, YYYY-MM-DD. Defaults to today in Ecuador; it cannot be later.",
            "example": "2026-10-15",
            "format": "date"
          },
          "sequential": {
            "type": "integer",
            "description": "Sequential to use instead of the next one, for example when migrating from another system. It must not be used yet; later automatic sequentials continue after the highest one used. Not accepted with the shared demo issuer (422 demo_issuer_sequential_not_allowed).",
            "example": 1501,
            "minimum": 1,
            "maximum": 999999999
          },
          "additionalInfo": {
            "type": "object",
            "description": "Additional information printed on the document (name → value, 1 to 300 characters each). A document carries at most 15 fields including the legends Flashpi adds (RUC Proveedor, and Gran Contribuyente for large taxpayers), so at most 13 or 14 of yours.",
            "example": {
              "Order": "PO-4812"
            },
            "additionalProperties": {
              "type": "string",
              "minLength": 1,
              "maxLength": 300
            },
            "maxProperties": 15
          },
          "options": {
            "description": "Delivery options.",
            "allOf": [
              {
                "$ref": "#/components/schemas/DocumentOptions"
              }
            ]
          },
          "departureAddress": {
            "type": "string",
            "description": "Where the transport starts.",
            "example": "Km 12 vía a Daule, Guayaquil",
            "minLength": 1,
            "maxLength": 300
          },
          "carrier": {
            "description": "The carrier.",
            "allOf": [
              {
                "$ref": "#/components/schemas/WaybillCarrier"
              }
            ]
          },
          "licensePlate": {
            "type": "string",
            "description": "License plate of the vehicle.",
            "example": "GBA1234",
            "minLength": 1,
            "maxLength": 20
          },
          "transportStartDate": {
            "type": "string",
            "description": "Start of the transport; not before the issue date.",
            "example": "2026-10-15",
            "format": "date"
          },
          "transportEndDate": {
            "type": "string",
            "description": "End of the transport; not before its start.",
            "example": "2026-10-16",
            "format": "date"
          },
          "recipients": {
            "description": "The recipients and their goods.",
            "minItems": 1,
            "maxItems": 100,
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/WaybillRecipient"
            }
          }
        },
        "description": "A waybill (guía de remisión) that supports the transport of goods.",
        "required": [
          "issuerId",
          "establishment",
          "emissionPoint",
          "departureAddress",
          "carrier",
          "licensePlate",
          "transportStartDate",
          "transportEndDate",
          "recipients"
        ]
      },
      "WithheldSubject": {
        "type": "object",
        "properties": {
          "idType": {
            "type": "string",
            "description": "Identification type (not `final_consumer`).",
            "example": "ruc",
            "enum": [
              "ruc",
              "cedula",
              "passport",
              "final_consumer",
              "foreign_id"
            ]
          },
          "id": {
            "type": "string",
            "description": "Identification number.",
            "example": "1790000000001",
            "minLength": 1,
            "maxLength": 20
          },
          "name": {
            "type": "string",
            "description": "Legal name.",
            "example": "Distribuidora del Pacífico S.A.",
            "minLength": 1,
            "maxLength": 300
          },
          "relatedParty": {
            "type": "boolean",
            "description": "Whether the supplier is a related party.",
            "example": false
          },
          "subjectType": {
            "type": "string",
            "description": "Required when `idType` is `foreign_id`: `individual` or `company`.",
            "example": "company",
            "enum": [
              "individual",
              "company"
            ]
          },
          "email": {
            "type": "string",
            "description": "Where the authorized receipt is emailed (see `options.sendEmail`).",
            "example": "facturacion@example.com",
            "format": "email",
            "maxLength": 320
          }
        },
        "description": "The supplier whose taxes are withheld.",
        "required": [
          "idType",
          "id",
          "name",
          "relatedParty"
        ]
      },
      "WithholdingForeignPayment": {
        "type": "object",
        "properties": {
          "regime": {
            "type": "string",
            "description": "Tax regime of the country of payment: `general`, `tax_haven` or `preferential` (preferential regime or lower-tax jurisdiction).",
            "example": "general",
            "enum": [
              "general",
              "tax_haven",
              "preferential"
            ]
          },
          "country": {
            "type": "string",
            "description": "Country of payment, as the SRI country code (3 or 4 digits).",
            "example": "212",
            "pattern": "^\\d{3,4}$"
          },
          "doubleTaxationTreatyApplies": {
            "type": "boolean",
            "description": "Whether a double taxation treaty applies.",
            "example": false
          },
          "subjectToWithholdingUnderLaw": {
            "type": "boolean",
            "description": "Whether the payment is subject to withholding under the law. Required when no double taxation treaty applies.",
            "example": true
          },
          "preferentialTaxRegime": {
            "type": "boolean",
            "description": "Whether it is a payment to a preferential tax regime.",
            "example": false
          }
        },
        "description": "Required when the payment goes abroad (`paymentResidence` is `foreign`).",
        "required": [
          "regime",
          "country",
          "doubleTaxationTreatyApplies",
          "preferentialTaxRegime"
        ]
      },
      "SupportingDocumentTax": {
        "type": "object",
        "properties": {
          "type": {
            "type": "string",
            "description": "Tax type: `vat`.",
            "example": "vat",
            "enum": [
              "vat"
            ]
          },
          "rate": {
            "type": "string",
            "description": "VAT rate in force on the supporting document issue date.",
            "example": "15",
            "enum": [
              "0",
              "5",
              "8",
              "12",
              "13",
              "14",
              "15",
              "exempt",
              "not_subject"
            ]
          },
          "taxableBase": {
            "type": "string",
            "description": "Taxable base.",
            "example": "1000.00",
            "pattern": "^\\d{1,12}(\\.\\d{1,2}0*)?$"
          },
          "amount": {
            "type": "string",
            "description": "The supporting document's VAT amount. Defaults to base × rate, rounded.",
            "example": "150.00",
            "pattern": "^\\d{1,12}(\\.\\d{1,2}0*)?$"
          }
        },
        "description": "A VAT of the supporting document.",
        "required": [
          "type",
          "rate",
          "taxableBase"
        ]
      },
      "WithholdingDividends": {
        "type": "object",
        "properties": {
          "paymentDate": {
            "type": "string",
            "description": "Dividend payment date.",
            "example": "2026-10-01",
            "format": "date"
          },
          "corporateIncomeTax": {
            "type": "string",
            "description": "Corporate income tax attributable to the dividends.",
            "example": "102.54",
            "pattern": "^\\d{1,12}(\\.\\d{1,2}0*)?$"
          },
          "profitFiscalYear": {
            "type": "string",
            "description": "Fiscal year of the distributed profits.",
            "example": "2025",
            "pattern": "^(19|20)\\d{2}$"
          }
        },
        "description": "Required when `taxSupportCode` is 10.",
        "required": [
          "paymentDate",
          "corporateIncomeTax",
          "profitFiscalYear"
        ]
      },
      "WithholdingBananaBoxes": {
        "type": "object",
        "properties": {
          "count": {
            "type": "integer",
            "description": "Number of boxes.",
            "example": 1200,
            "minimum": 1,
            "maximum": 9999999
          },
          "pricePerBox": {
            "type": "string",
            "description": "Price per box.",
            "example": "6.50",
            "pattern": "^\\d{1,12}(\\.\\d{1,2}0*)?$"
          }
        },
        "description": "Required for the banana box income tax codes (338, 340, 341, 342, 342A, 342B).",
        "required": [
          "count",
          "pricePerBox"
        ]
      },
      "Withholding": {
        "type": "object",
        "properties": {
          "tax": {
            "type": "string",
            "description": "Tax withheld: `income_tax`, `vat` or `isd`.",
            "example": "vat",
            "enum": [
              "income_tax",
              "vat",
              "isd"
            ]
          },
          "code": {
            "type": "string",
            "description": "Withholding code: TABLA 20 for `vat` (for example `1` = 30%, `2` = 70%, `3` = 100%) and `isd`, the Catálogo ATS for `income_tax` (for example `312`).",
            "example": "1",
            "pattern": "^[A-Za-z0-9]{1,5}$"
          },
          "taxableBase": {
            "type": "string",
            "description": "Taxable base of the withholding.",
            "example": "150.00",
            "pattern": "^\\d{1,12}(\\.\\d{1,2}0*)?$"
          },
          "rate": {
            "type": "string",
            "description": "Percentage. Required for `income_tax`; for `vat` and `isd` Flashpi takes it from the code, and a different value is refused.",
            "example": "30",
            "pattern": "^\\d{1,3}(\\.\\d{1,2}0*)?$"
          },
          "dividends": {
            "description": "Dividend details.",
            "allOf": [
              {
                "$ref": "#/components/schemas/WithholdingDividends"
              }
            ]
          },
          "bananaBoxes": {
            "description": "Banana box purchase.",
            "allOf": [
              {
                "$ref": "#/components/schemas/WithholdingBananaBoxes"
              }
            ]
          }
        },
        "description": "A withholding. Flashpi computes the withheld amount: taxable base × percentage, rounded to 2 decimals.",
        "required": [
          "tax",
          "code",
          "taxableBase"
        ]
      },
      "WithholdingPayment": {
        "type": "object",
        "properties": {
          "method": {
            "type": "string",
            "description": "Payment method (same values as `DocumentPayment.method`).",
            "example": "other_financial_system",
            "enum": [
              "cash",
              "debt_offset",
              "debit_card",
              "electronic_money",
              "prepaid_card",
              "credit_card",
              "other_financial_system",
              "securities_endorsement"
            ]
          },
          "amount": {
            "type": "string",
            "description": "Amount.",
            "example": "1150.00",
            "pattern": "^\\d{1,12}(\\.\\d{1,2}0*)?$"
          }
        },
        "description": "A payment of the supporting document.",
        "required": [
          "method",
          "amount"
        ]
      },
      "SupportingDocument": {
        "type": "object",
        "properties": {
          "taxSupportCode": {
            "type": "string",
            "description": "Tax support code (Catálogo ATS tabla 5), for example `01`.",
            "example": "01",
            "pattern": "^\\d{2}$"
          },
          "documentTypeCode": {
            "type": "string",
            "description": "Document type code (Catálogo ATS tabla 4), for example `01` for an invoice.",
            "example": "01",
            "pattern": "^\\d{2,3}$"
          },
          "number": {
            "type": "string",
            "description": "Its number.",
            "example": "001-002-000004567",
            "pattern": "^\\d{3}-\\d{3}-\\d{9}$"
          },
          "issueDate": {
            "type": "string",
            "description": "Its issue date, on or before the withholding.",
            "example": "2026-10-10",
            "format": "date"
          },
          "accountingDate": {
            "type": "string",
            "description": "Accounting record date.",
            "example": "2026-10-10",
            "format": "date"
          },
          "authorizationNumber": {
            "type": "string",
            "description": "Its authorization number (10, 37 or 49 digits).",
            "example": "1010202601099000000000110010020000045678765432117",
            "pattern": "^(\\d{10}|\\d{37}|\\d{49})$"
          },
          "paymentResidence": {
            "type": "string",
            "description": "Whether the payment is `local` or `foreign`. Defaults to `local`.",
            "example": "local",
            "enum": [
              "local",
              "foreign"
            ]
          },
          "foreignPayment": {
            "description": "Foreign payment details; required for a `foreign` payment.",
            "allOf": [
              {
                "$ref": "#/components/schemas/WithholdingForeignPayment"
              }
            ]
          },
          "subtotal": {
            "type": "string",
            "description": "Its subtotal before taxes.",
            "example": "1000.00",
            "pattern": "^\\d{1,12}(\\.\\d{1,2}0*)?$"
          },
          "total": {
            "type": "string",
            "description": "Its total.",
            "example": "1150.00",
            "pattern": "^\\d{1,12}(\\.\\d{1,2}0*)?$"
          },
          "taxes": {
            "description": "Its taxes.",
            "minItems": 1,
            "maxItems": 10,
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/SupportingDocumentTax"
            }
          },
          "withholdings": {
            "description": "What is withheld from it.",
            "minItems": 1,
            "maxItems": 20,
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Withholding"
            }
          },
          "payments": {
            "description": "How it is paid; the payments must add up to its total.",
            "minItems": 1,
            "maxItems": 50,
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/WithholdingPayment"
            }
          }
        },
        "description": "The supplier document whose taxes are withheld, usually an invoice.",
        "required": [
          "taxSupportCode",
          "documentTypeCode",
          "number",
          "issueDate",
          "subtotal",
          "total",
          "taxes",
          "withholdings",
          "payments"
        ]
      },
      "CreateWithholding": {
        "type": "object",
        "properties": {
          "issuerId": {
            "type": "string",
            "format": "uuid",
            "example": "01a13eca-2e80-7c3d-9f21-5b8e4a6d0c17",
            "description": "The issuer (taxpayer) that issues the document."
          },
          "establishment": {
            "type": "string",
            "description": "Establishment code (3 digits) registered on the issuer.",
            "example": "001",
            "pattern": "^\\d{3}$"
          },
          "emissionPoint": {
            "type": "string",
            "description": "Emission point code (3 digits) registered on the establishment.",
            "example": "001",
            "pattern": "^\\d{3}$"
          },
          "issueDate": {
            "type": "string",
            "description": "Issue date, YYYY-MM-DD. Defaults to today in Ecuador; it cannot be later.",
            "example": "2026-10-15",
            "format": "date"
          },
          "sequential": {
            "type": "integer",
            "description": "Sequential to use instead of the next one, for example when migrating from another system. It must not be used yet; later automatic sequentials continue after the highest one used. Not accepted with the shared demo issuer (422 demo_issuer_sequential_not_allowed).",
            "example": 1501,
            "minimum": 1,
            "maximum": 999999999
          },
          "additionalInfo": {
            "type": "object",
            "description": "Additional information printed on the document (name → value, 1 to 300 characters each). A document carries at most 15 fields including the legends Flashpi adds (RUC Proveedor, and Gran Contribuyente for large taxpayers), so at most 13 or 14 of yours.",
            "example": {
              "Order": "PO-4812"
            },
            "additionalProperties": {
              "type": "string",
              "minLength": 1,
              "maxLength": 300
            },
            "maxProperties": 15
          },
          "options": {
            "description": "Delivery options.",
            "allOf": [
              {
                "$ref": "#/components/schemas/DocumentOptions"
              }
            ]
          },
          "subject": {
            "description": "The withheld supplier.",
            "allOf": [
              {
                "$ref": "#/components/schemas/WithheldSubject"
              }
            ]
          },
          "fiscalPeriod": {
            "type": "string",
            "description": "Fiscal period, YYYY-MM. Defaults to the month of the issue date.",
            "example": "2026-10",
            "pattern": "^\\d{4}-\\d{2}$"
          },
          "supportingDocuments": {
            "description": "The supporting documents and their withholdings.",
            "minItems": 1,
            "maxItems": 50,
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/SupportingDocument"
            }
          },
          "expectedTotal": {
            "type": "string",
            "description": "The total withheld you expect; when it differs from the computed one the request is refused with 422 total_mismatch.",
            "example": "10.35",
            "pattern": "^\\d{1,12}(\\.\\d{1,2}0*)?$"
          }
        },
        "description": "A withholding receipt (comprobante de retención). Flashpi computes every withheld amount and the total withheld.",
        "required": [
          "issuerId",
          "establishment",
          "emissionPoint",
          "subject",
          "supportingDocuments"
        ]
      },
      "DocumentList": {
        "type": "object",
        "properties": {
          "data": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Document"
            }
          },
          "pagination": {
            "$ref": "#/components/schemas/Pagination"
          }
        },
        "description": "A page of documents, newest first.",
        "required": [
          "data",
          "pagination"
        ]
      },
      "SendDocumentEmail": {
        "type": "object",
        "properties": {},
        "description": "No options yet: send an empty object or no body."
      },
      "CreateWebhookEndpoint": {
        "type": "object",
        "properties": {
          "url": {
            "type": "string",
            "maxLength": 2048,
            "example": "https://hooks.example.com/flashpi",
            "description": "Where Flashpi POSTs the events: a public HTTPS URL without credentials or fragment. Changing it requires a new verification."
          },
          "description": {
            "type": [
              "string",
              "null"
            ],
            "maxLength": 500,
            "example": "ERP production receiver",
            "description": "A label for your own reference."
          },
          "enabledEvents": {
            "type": "array",
            "minItems": 1,
            "maxItems": 100,
            "example": [
              "invoice.authorized",
              "invoice.rejected"
            ],
            "description": "Event types the endpoint receives; `*` receives every type, including future ones.",
            "items": {
              "type": "string",
              "enum": [
                "invoice.authorized",
                "invoice.rejected",
                "purchase_settlement.authorized",
                "purchase_settlement.rejected",
                "credit_note.authorized",
                "credit_note.rejected",
                "debit_note.authorized",
                "debit_note.rejected",
                "waybill.authorized",
                "waybill.rejected",
                "withholding.authorized",
                "withholding.rejected",
                "certificate.verified",
                "certificate.pending",
                "certificate.blocked",
                "certificate.revoked",
                "certificate.reactivated",
                "document.ride.generated",
                "document.ride.failed",
                "document.email.sent",
                "document.email.delivered",
                "document.email.bounced",
                "document.email.complained",
                "document.email.failed",
                "account.email_paused",
                "account.email_resumed",
                "*"
              ]
            }
          },
          "payloadMode": {
            "type": "string",
            "enum": [
              "full",
              "thin"
            ],
            "description": "`full` (default): the event with a snapshot of its resource in `data`. `thin`: the event without `data`, only `id`, `type`, `environment` and `createdAt` (read the snapshot with GET /v1/events/{id}).",
            "default": "full"
          }
        },
        "required": [
          "url",
          "enabledEvents"
        ]
      },
      "WebhookEndpointVerification": {
        "type": "object",
        "properties": {
          "verifiedAt": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          },
          "inProgress": {
            "type": "boolean",
            "description": "Whether a handshake attempt is scheduled or running."
          },
          "attempts": {
            "type": "number",
            "example": 1,
            "description": "Attempts of the current handshake."
          },
          "lastAttemptAt": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          },
          "lastError": {
            "type": [
              "string",
              "null"
            ],
            "example": "challenge_mismatch",
            "description": "Why the last attempt failed: `challenge_mismatch`, `unexpected_status`, `timeout`, `connection_failed`, `dns_resolution_failed`, `tls_error`, `address_not_allowed` or `invalid_url`."
          },
          "lastResponseStatus": {
            "type": [
              "integer",
              "null"
            ],
            "example": 200
          }
        },
        "description": "The activation handshake: Flashpi POSTs a signed `webhook_endpoint.verification` body with a `challenge`, and the endpoint must answer 2xx echoing it.",
        "required": [
          "verifiedAt",
          "inProgress",
          "attempts",
          "lastAttemptAt",
          "lastError",
          "lastResponseStatus"
        ]
      },
      "WebhookEndpoint": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid",
            "example": "01a1407e-5b1c-7d7a-9c55-0e4bb9e9a001"
          },
          "url": {
            "type": "string",
            "maxLength": 2048,
            "example": "https://hooks.example.com/flashpi",
            "description": "Where Flashpi POSTs the events: a public HTTPS URL without credentials or fragment. Changing it requires a new verification."
          },
          "description": {
            "type": [
              "string",
              "null"
            ],
            "maxLength": 500,
            "example": "ERP production receiver",
            "description": "A label for your own reference."
          },
          "enabledEvents": {
            "type": "array",
            "minItems": 1,
            "maxItems": 100,
            "example": [
              "invoice.authorized",
              "invoice.rejected"
            ],
            "description": "Event types the endpoint receives; `*` receives every type, including future ones.",
            "items": {
              "type": "string",
              "enum": [
                "invoice.authorized",
                "invoice.rejected",
                "purchase_settlement.authorized",
                "purchase_settlement.rejected",
                "credit_note.authorized",
                "credit_note.rejected",
                "debit_note.authorized",
                "debit_note.rejected",
                "waybill.authorized",
                "waybill.rejected",
                "withholding.authorized",
                "withholding.rejected",
                "certificate.verified",
                "certificate.pending",
                "certificate.blocked",
                "certificate.revoked",
                "certificate.reactivated",
                "document.ride.generated",
                "document.ride.failed",
                "document.email.sent",
                "document.email.delivered",
                "document.email.bounced",
                "document.email.complained",
                "document.email.failed",
                "account.email_paused",
                "account.email_resumed",
                "*"
              ]
            }
          },
          "payloadMode": {
            "type": "string",
            "enum": [
              "full",
              "thin"
            ],
            "description": "`full` (default): the event with a snapshot of its resource in `data`. `thin`: the event without `data`, only `id`, `type`, `environment` and `createdAt` (read the snapshot with GET /v1/events/{id})."
          },
          "status": {
            "type": "string",
            "enum": [
              "pending_verification",
              "active",
              "disabled"
            ],
            "example": "active",
            "description": "`pending_verification` (receives nothing until it echoes the challenge), `active` or `disabled`."
          },
          "environment": {
            "type": "string",
            "enum": [
              "test",
              "live"
            ],
            "description": "Mode of the events it receives."
          },
          "verification": {
            "$ref": "#/components/schemas/WebhookEndpointVerification"
          },
          "previousSecretExpiresAt": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time",
            "description": "After a rotation: until when deliveries are also signed with the previous secret."
          },
          "disabledAt": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          },
          "updatedAt": {
            "type": "string",
            "format": "date-time"
          }
        },
        "description": "A URL that receives Standard Webhooks, signed with a whsec_ secret (read it with GET .../secret). It receives the events of the mode of the API key that created it (test or live).",
        "required": [
          "id",
          "url",
          "description",
          "enabledEvents",
          "payloadMode",
          "status",
          "environment",
          "verification",
          "previousSecretExpiresAt",
          "disabledAt",
          "createdAt",
          "updatedAt"
        ]
      },
      "WebhookEndpointList": {
        "type": "object",
        "properties": {
          "data": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/WebhookEndpoint"
            }
          },
          "pagination": {
            "$ref": "#/components/schemas/Pagination"
          }
        },
        "description": "A page of webhook endpoints, newest first.",
        "required": [
          "data",
          "pagination"
        ]
      },
      "UpdateWebhookEndpoint": {
        "type": "object",
        "properties": {
          "url": {
            "type": "string",
            "maxLength": 2048,
            "example": "https://hooks.example.com/flashpi",
            "description": "Where Flashpi POSTs the events: a public HTTPS URL without credentials or fragment. Changing it requires a new verification."
          },
          "description": {
            "type": [
              "string",
              "null"
            ],
            "maxLength": 500,
            "example": "ERP production receiver",
            "description": "A label for your own reference."
          },
          "enabledEvents": {
            "type": "array",
            "minItems": 1,
            "maxItems": 100,
            "example": [
              "invoice.authorized",
              "invoice.rejected"
            ],
            "description": "Event types the endpoint receives; `*` receives every type, including future ones.",
            "items": {
              "type": "string",
              "enum": [
                "invoice.authorized",
                "invoice.rejected",
                "purchase_settlement.authorized",
                "purchase_settlement.rejected",
                "credit_note.authorized",
                "credit_note.rejected",
                "debit_note.authorized",
                "debit_note.rejected",
                "waybill.authorized",
                "waybill.rejected",
                "withholding.authorized",
                "withholding.rejected",
                "certificate.verified",
                "certificate.pending",
                "certificate.blocked",
                "certificate.revoked",
                "certificate.reactivated",
                "document.ride.generated",
                "document.ride.failed",
                "document.email.sent",
                "document.email.delivered",
                "document.email.bounced",
                "document.email.complained",
                "document.email.failed",
                "account.email_paused",
                "account.email_resumed",
                "*"
              ]
            }
          },
          "payloadMode": {
            "type": "string",
            "enum": [
              "full",
              "thin"
            ],
            "description": "`full` (default): the event with a snapshot of its resource in `data`. `thin`: the event without `data`, only `id`, `type`, `environment` and `createdAt` (read the snapshot with GET /v1/events/{id})."
          },
          "disabled": {
            "type": "boolean",
            "description": "true disables the endpoint (pending deliveries end); false enables it again (a new verification is sent when it was never verified).",
            "example": false
          }
        },
        "description": "Fields to change; null clears the description."
      },
      "WebhookEndpointSecret": {
        "type": "object",
        "properties": {
          "secret": {
            "type": "string",
            "example": "whsec_c2VjcmV0LXNlY3JldC1zZWNyZXQtc2VjcmV0LXNlYw==",
            "description": "The current whsec_ secret (Standard Webhooks): base64 of the HMAC-SHA256 key after the prefix."
          },
          "previousSecretExpiresAt": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time",
            "description": "After a rotation: until when the previous secret also signs."
          }
        },
        "description": "The signing secret of an endpoint.",
        "required": [
          "secret",
          "previousSecretExpiresAt"
        ]
      },
      "RotateWebhookEndpointSecret": {
        "type": "object",
        "properties": {
          "previousSecretExpiresInHours": {
            "type": "integer",
            "description": "Hours the previous secret keeps signing deliveries next to the new one (default 24, at most 168); 0 drops it at once.",
            "example": 24,
            "minimum": 0,
            "maximum": 168
          }
        }
      },
      "WebhookDelivery": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "webhookEndpointId": {
            "type": "string",
            "format": "uuid"
          },
          "eventId": {
            "type": "string",
            "format": "uuid",
            "description": "The event, also the webhook-id header."
          },
          "eventType": {
            "type": "string",
            "enum": [
              "invoice.authorized",
              "invoice.rejected",
              "purchase_settlement.authorized",
              "purchase_settlement.rejected",
              "credit_note.authorized",
              "credit_note.rejected",
              "debit_note.authorized",
              "debit_note.rejected",
              "waybill.authorized",
              "waybill.rejected",
              "withholding.authorized",
              "withholding.rejected",
              "certificate.verified",
              "certificate.pending",
              "certificate.blocked",
              "certificate.revoked",
              "certificate.reactivated",
              "document.ride.generated",
              "document.ride.failed",
              "document.email.sent",
              "document.email.delivered",
              "document.email.bounced",
              "document.email.complained",
              "document.email.failed",
              "account.email_paused",
              "account.email_resumed"
            ],
            "example": "invoice.authorized"
          },
          "payloadMode": {
            "type": "string",
            "enum": [
              "full",
              "thin"
            ],
            "example": "full"
          },
          "status": {
            "type": "string",
            "enum": [
              "pending",
              "succeeded",
              "failed"
            ],
            "example": "succeeded",
            "description": "`pending` (an attempt is scheduled or running), `succeeded` or `failed`."
          },
          "attemptCount": {
            "type": "number",
            "example": 1
          },
          "nextAttemptAt": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          },
          "lastAttemptAt": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          },
          "lastResponseStatus": {
            "type": [
              "integer",
              "null"
            ],
            "example": 200
          },
          "lastError": {
            "type": [
              "string",
              "null"
            ],
            "example": null,
            "description": "Why it failed: `unexpected_status` (an answer other than 2xx, see the status), `timeout`, `connection_failed`, `dns_resolution_failed`, `tls_error`, `address_not_allowed`, `invalid_url`, or without an attempt `endpoint_disabled` and `endpoint_not_verified`."
          },
          "succeededAt": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          },
          "retryUntil": {
            "type": "string",
            "format": "date-time",
            "description": "No automatic attempt after this time."
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          },
          "updatedAt": {
            "type": "string",
            "format": "date-time"
          }
        },
        "description": "One event sent to one endpoint, retried with backoff for 72 hours until it gets a 2xx.",
        "required": [
          "id",
          "webhookEndpointId",
          "eventId",
          "eventType",
          "payloadMode",
          "status",
          "attemptCount",
          "nextAttemptAt",
          "lastAttemptAt",
          "lastResponseStatus",
          "lastError",
          "succeededAt",
          "retryUntil",
          "createdAt",
          "updatedAt"
        ]
      },
      "WebhookDeliveryList": {
        "type": "object",
        "properties": {
          "data": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/WebhookDelivery"
            }
          },
          "pagination": {
            "$ref": "#/components/schemas/Pagination"
          }
        },
        "description": "A page of deliveries, newest first.",
        "required": [
          "data",
          "pagination"
        ]
      },
      "WebhookDeliveryAttempt": {
        "type": "object",
        "properties": {
          "number": {
            "type": "number",
            "example": 1,
            "description": "1 for the first attempt."
          },
          "trigger": {
            "type": "string",
            "enum": [
              "automatic",
              "replay"
            ],
            "example": "automatic"
          },
          "startedAt": {
            "type": "string",
            "format": "date-time"
          },
          "durationMs": {
            "type": "number",
            "example": 182
          },
          "responseStatus": {
            "type": [
              "integer",
              "null"
            ],
            "example": 200
          },
          "error": {
            "type": [
              "string",
              "null"
            ],
            "example": null,
            "description": "Why it failed: `unexpected_status` (an answer other than 2xx, see the status), `timeout`, `connection_failed`, `dns_resolution_failed`, `tls_error`, `address_not_allowed`, `invalid_url`, or without an attempt `endpoint_disabled` and `endpoint_not_verified`."
          },
          "succeeded": {
            "type": "boolean",
            "example": true
          }
        },
        "description": "One HTTP attempt of a delivery.",
        "required": [
          "number",
          "trigger",
          "startedAt",
          "durationMs",
          "responseStatus",
          "error",
          "succeeded"
        ]
      },
      "WebhookDeliveryDetail": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "webhookEndpointId": {
            "type": "string",
            "format": "uuid"
          },
          "eventId": {
            "type": "string",
            "format": "uuid",
            "description": "The event, also the webhook-id header."
          },
          "eventType": {
            "type": "string",
            "enum": [
              "invoice.authorized",
              "invoice.rejected",
              "purchase_settlement.authorized",
              "purchase_settlement.rejected",
              "credit_note.authorized",
              "credit_note.rejected",
              "debit_note.authorized",
              "debit_note.rejected",
              "waybill.authorized",
              "waybill.rejected",
              "withholding.authorized",
              "withholding.rejected",
              "certificate.verified",
              "certificate.pending",
              "certificate.blocked",
              "certificate.revoked",
              "certificate.reactivated",
              "document.ride.generated",
              "document.ride.failed",
              "document.email.sent",
              "document.email.delivered",
              "document.email.bounced",
              "document.email.complained",
              "document.email.failed",
              "account.email_paused",
              "account.email_resumed"
            ],
            "example": "invoice.authorized"
          },
          "payloadMode": {
            "type": "string",
            "enum": [
              "full",
              "thin"
            ],
            "example": "full"
          },
          "status": {
            "type": "string",
            "enum": [
              "pending",
              "succeeded",
              "failed"
            ],
            "example": "succeeded",
            "description": "`pending` (an attempt is scheduled or running), `succeeded` or `failed`."
          },
          "attemptCount": {
            "type": "number",
            "example": 1
          },
          "nextAttemptAt": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          },
          "lastAttemptAt": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          },
          "lastResponseStatus": {
            "type": [
              "integer",
              "null"
            ],
            "example": 200
          },
          "lastError": {
            "type": [
              "string",
              "null"
            ],
            "example": null,
            "description": "Why it failed: `unexpected_status` (an answer other than 2xx, see the status), `timeout`, `connection_failed`, `dns_resolution_failed`, `tls_error`, `address_not_allowed`, `invalid_url`, or without an attempt `endpoint_disabled` and `endpoint_not_verified`."
          },
          "succeededAt": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          },
          "retryUntil": {
            "type": "string",
            "format": "date-time",
            "description": "No automatic attempt after this time."
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          },
          "updatedAt": {
            "type": "string",
            "format": "date-time"
          },
          "attempts": {
            "description": "Oldest first.",
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/WebhookDeliveryAttempt"
            }
          }
        },
        "description": "A delivery with its attempts.",
        "required": [
          "id",
          "webhookEndpointId",
          "eventId",
          "eventType",
          "payloadMode",
          "status",
          "attemptCount",
          "nextAttemptAt",
          "lastAttemptAt",
          "lastResponseStatus",
          "lastError",
          "succeededAt",
          "retryUntil",
          "createdAt",
          "updatedAt",
          "attempts"
        ]
      },
      "AccountEmailSendingWindow": {
        "type": "object",
        "properties": {
          "since": {
            "type": "string",
            "format": "date-time",
            "description": "Where the counted period starts."
          },
          "sent": {
            "type": "number",
            "example": 120,
            "description": "Emails the email provider accepted."
          },
          "hardBounces": {
            "type": "number",
            "example": 2,
            "description": "Of those, hard bounces (`bounce_permanent`: the address or the domain does not exist)."
          },
          "complaints": {
            "type": "number",
            "example": 0,
            "description": "Of those, emails the recipient marked as spam."
          }
        },
        "description": "The buyer emails the account sent in the last 7 days in this mode (since Flashpi's staff last resumed them, when that is later).",
        "required": [
          "since",
          "sent",
          "hardBounces",
          "complaints"
        ]
      },
      "AccountEmailSending": {
        "type": "object",
        "properties": {
          "environment": {
            "type": "string",
            "enum": [
              "test",
              "live"
            ],
            "example": "live"
          },
          "status": {
            "type": "string",
            "enum": [
              "active",
              "paused"
            ],
            "example": "active"
          },
          "pausedAt": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time",
            "example": null
          },
          "pauseReason": {
            "type": [
              "string",
              "null"
            ],
            "enum": [
              "bounce_rate",
              "complaint_rate",
              "staff",
              null
            ],
            "example": null,
            "description": "Set while paused: `bounce_rate` (hard bounces), `complaint_rate` (complaints) or `staff` (Flashpi's staff paused them)."
          },
          "window": {
            "$ref": "#/components/schemas/AccountEmailSendingWindow"
          }
        },
        "description": "Whether the account's buyer emails of one mode go out. Flashpi pauses them when the last 7 days have at least 3 hard bounces and 3 % of the emails sent, or at least 2 complaints and 0.05 % (they protect the email provider's reputation that every customer shares). While paused, documents are still issued and authorized; their emails fail with `email_sending_paused` and resends answer 409 `email_sending_paused`. Only Flashpi's staff resume them.",
        "required": [
          "environment",
          "status",
          "pausedAt",
          "pauseReason",
          "window"
        ]
      },
      "Event": {
        "description": "Something that happened to a resource. The webhook body is this same object (without `data` for thin endpoints), and `id` is its webhook-id header.",
        "oneOf": [
          {
            "$ref": "#/components/schemas/DocumentEvent"
          },
          {
            "$ref": "#/components/schemas/CertificateEvent"
          },
          {
            "$ref": "#/components/schemas/AccountEvent"
          }
        ],
        "discriminator": {
          "propertyName": "type",
          "mapping": {
            "invoice.authorized": "#/components/schemas/DocumentEvent",
            "invoice.rejected": "#/components/schemas/DocumentEvent",
            "purchase_settlement.authorized": "#/components/schemas/DocumentEvent",
            "purchase_settlement.rejected": "#/components/schemas/DocumentEvent",
            "credit_note.authorized": "#/components/schemas/DocumentEvent",
            "credit_note.rejected": "#/components/schemas/DocumentEvent",
            "debit_note.authorized": "#/components/schemas/DocumentEvent",
            "debit_note.rejected": "#/components/schemas/DocumentEvent",
            "waybill.authorized": "#/components/schemas/DocumentEvent",
            "waybill.rejected": "#/components/schemas/DocumentEvent",
            "withholding.authorized": "#/components/schemas/DocumentEvent",
            "withholding.rejected": "#/components/schemas/DocumentEvent",
            "certificate.verified": "#/components/schemas/CertificateEvent",
            "certificate.pending": "#/components/schemas/CertificateEvent",
            "certificate.blocked": "#/components/schemas/CertificateEvent",
            "certificate.revoked": "#/components/schemas/CertificateEvent",
            "certificate.reactivated": "#/components/schemas/CertificateEvent",
            "document.ride.generated": "#/components/schemas/DocumentEvent",
            "document.ride.failed": "#/components/schemas/DocumentEvent",
            "document.email.sent": "#/components/schemas/DocumentEvent",
            "document.email.delivered": "#/components/schemas/DocumentEvent",
            "document.email.bounced": "#/components/schemas/DocumentEvent",
            "document.email.complained": "#/components/schemas/DocumentEvent",
            "document.email.failed": "#/components/schemas/DocumentEvent",
            "account.email_paused": "#/components/schemas/AccountEvent",
            "account.email_resumed": "#/components/schemas/AccountEvent"
          }
        }
      },
      "EventList": {
        "type": "object",
        "properties": {
          "data": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Event"
            }
          },
          "pagination": {
            "$ref": "#/components/schemas/Pagination"
          }
        },
        "description": "A page of events, newest first.",
        "required": [
          "data",
          "pagination"
        ]
      },
      "DocumentEvent": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid",
            "example": "01a14082-3c1d-7f0e-8b2a-6d5e4f3a2b10"
          },
          "type": {
            "type": "string",
            "enum": [
              "invoice.authorized",
              "invoice.rejected",
              "purchase_settlement.authorized",
              "purchase_settlement.rejected",
              "credit_note.authorized",
              "credit_note.rejected",
              "debit_note.authorized",
              "debit_note.rejected",
              "waybill.authorized",
              "waybill.rejected",
              "withholding.authorized",
              "withholding.rejected",
              "document.ride.generated",
              "document.ride.failed",
              "document.email.sent",
              "document.email.delivered",
              "document.email.bounced",
              "document.email.complained",
              "document.email.failed"
            ],
            "example": "invoice.authorized"
          },
          "environment": {
            "type": "string",
            "enum": [
              "test",
              "live"
            ],
            "description": "Mode of the resource."
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          },
          "data": {
            "$ref": "#/components/schemas/Document"
          }
        },
        "description": "An event about a document (its tax outcome, RIDE or email): `data` is the Document as the API returned it when the event happened (texts in English).",
        "required": [
          "id",
          "type",
          "environment",
          "createdAt",
          "data"
        ],
        "title": "Document event"
      },
      "CertificateEvent": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid",
            "example": "01a14082-3c1d-7f0e-8b2a-6d5e4f3a2b10"
          },
          "type": {
            "type": "string",
            "enum": [
              "certificate.verified",
              "certificate.pending",
              "certificate.blocked",
              "certificate.revoked",
              "certificate.reactivated"
            ],
            "example": "certificate.verified"
          },
          "environment": {
            "type": "string",
            "enum": [
              "test",
              "live"
            ],
            "description": "Mode of the resource."
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          },
          "data": {
            "$ref": "#/components/schemas/Certificate"
          }
        },
        "description": "An event about a .p12 certificate: `data` is the Certificate as the API returned it when the event happened (texts in English).",
        "required": [
          "id",
          "type",
          "environment",
          "createdAt",
          "data"
        ],
        "title": "Certificate event"
      },
      "AccountEvent": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid",
            "example": "01a14082-3c1d-7f0e-8b2a-6d5e4f3a2b10"
          },
          "type": {
            "type": "string",
            "enum": [
              "account.email_paused",
              "account.email_resumed"
            ],
            "example": "account.email_paused"
          },
          "environment": {
            "type": "string",
            "enum": [
              "test",
              "live"
            ],
            "description": "Mode of the resource."
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          },
          "data": {
            "$ref": "#/components/schemas/AccountEmailSending"
          }
        },
        "description": "An event about the account's email sending: `data` is the AccountEmailSending as the API returned it when the event happened (texts in English).",
        "required": [
          "id",
          "type",
          "environment",
          "createdAt",
          "data"
        ],
        "title": "Account event"
      },
      "EventThin": {
        "type": "object",
        "description": "The body sent to `thin` endpoints: the event without its snapshot. Read it with GET /v1/events/{id}.",
        "not": {
          "required": [
            "data"
          ]
        },
        "required": [
          "id",
          "type",
          "environment",
          "createdAt"
        ],
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "type": {
            "type": "string",
            "enum": [
              "invoice.authorized",
              "invoice.rejected",
              "purchase_settlement.authorized",
              "purchase_settlement.rejected",
              "credit_note.authorized",
              "credit_note.rejected",
              "debit_note.authorized",
              "debit_note.rejected",
              "waybill.authorized",
              "waybill.rejected",
              "withholding.authorized",
              "withholding.rejected",
              "certificate.verified",
              "certificate.pending",
              "certificate.blocked",
              "certificate.revoked",
              "certificate.reactivated",
              "document.ride.generated",
              "document.ride.failed",
              "document.email.sent",
              "document.email.delivered",
              "document.email.bounced",
              "document.email.complained",
              "document.email.failed",
              "account.email_paused",
              "account.email_resumed"
            ]
          },
          "environment": {
            "type": "string",
            "enum": [
              "test",
              "live"
            ]
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          }
        }
      },
      "WebhookEndpointVerificationEvent": {
        "type": "object",
        "description": "The activation handshake of an endpoint, sent when it is created, when its URL changes and on POST /v1/webhook-endpoints/{id}/verify; every attempt has a new id and challenge. It is signed like every webhook; answer 2xx with `{\"challenge\": \"<data.challenge>\"}` (or the challenge as plain text).",
        "required": [
          "id",
          "type",
          "environment",
          "createdAt",
          "data"
        ],
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid",
            "description": "This attempt's id, also its webhook-id header: new on every attempt."
          },
          "type": {
            "type": "string",
            "const": "webhook_endpoint.verification"
          },
          "environment": {
            "type": "string",
            "enum": [
              "test",
              "live"
            ]
          },
          "createdAt": {
            "type": "string",
            "format": "date-time",
            "description": "When this attempt was sent."
          },
          "data": {
            "type": "object",
            "required": [
              "webhookEndpointId",
              "challenge"
            ],
            "properties": {
              "webhookEndpointId": {
                "type": "string",
                "format": "uuid"
              },
              "challenge": {
                "type": "string",
                "description": "Random value to echo back, new on every attempt: echo the one of this request."
              }
            }
          }
        }
      }
    },
    "headers": {
      "RequestId": {
        "description": "Flashpi's ID of the request, a UUIDv7 (also `requestId` in errors). Include it when you contact support.",
        "schema": {
          "type": "string",
          "format": "uuid"
        }
      },
      "WwwAuthenticate": {
        "description": "RFC 6750 challenge: `Bearer realm=\"flashpi\"`, plus `error=\"invalid_token\"` with `invalid_api_key`.",
        "schema": {
          "type": "string"
        }
      },
      "RetryAfter": {
        "description": "Whole seconds to wait before trying again.",
        "schema": {
          "type": "integer",
          "minimum": 1
        }
      }
    },
    "parameters": {
      "AcceptLanguage": {
        "name": "Accept-Language",
        "in": "header",
        "required": false,
        "description": "Language of error messages and of the localized texts of resources (SRI messages, failures, certificate rejections): Spanish when the entry with the highest q-value is `es` or `es-` plus a region (`es-EC`, `es-419`), English otherwise. Errors state it in Content-Language.",
        "schema": {
          "type": "string"
        }
      },
      "CorrelationId": {
        "name": "X-Correlation-Id",
        "in": "header",
        "required": false,
        "description": "Your own ID for the request (letters, digits and `-_.:/+=`), echoed back in the X-Correlation-Id response header and logged next to the request ID. An invalid value gets 400 invalid_correlation_id.",
        "schema": {
          "type": "string",
          "minLength": 1,
          "maxLength": 128,
          "pattern": "^[A-Za-z0-9._:/+=-]{1,128}$"
        }
      }
    }
  },
  "webhooks": {
    "invoice.authorized": {
      "post": {
        "operationId": "webhookInvoiceAuthorized",
        "summary": "invoice.authorized",
        "description": "The SRI authorized the document.",
        "tags": [
          "Webhooks"
        ],
        "parameters": [
          {
            "name": "webhook-id",
            "in": "header",
            "required": true,
            "description": "The event id (UUIDv7), the same on every attempt and replay: deduplicate on it.",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "webhook-timestamp",
            "in": "header",
            "required": true,
            "description": "Unix time (seconds) of this attempt. Refuse values more than 5 minutes from your clock.",
            "schema": {
              "type": "string",
              "pattern": "^\\d+$"
            }
          },
          {
            "name": "webhook-signature",
            "in": "header",
            "required": true,
            "description": "Space-separated `v1,<base64>` signatures: HMAC-SHA256 of `<webhook-id>.<webhook-timestamp>.<body>` with the base64-decoded part of the whsec_ secret. Accept the request if any of them matches (there is one per valid secret during a rotation).",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "oneOf": [
                  {
                    "$ref": "#/components/schemas/DocumentEvent"
                  },
                  {
                    "$ref": "#/components/schemas/EventThin"
                  }
                ]
              }
            }
          }
        },
        "responses": {
          "2XX": {
            "description": "Acknowledged. Anything else is retried."
          }
        }
      }
    },
    "invoice.rejected": {
      "post": {
        "operationId": "webhookInvoiceRejected",
        "summary": "invoice.rejected",
        "description": "The SRI rejected the document (see sriMessages).",
        "tags": [
          "Webhooks"
        ],
        "parameters": [
          {
            "name": "webhook-id",
            "in": "header",
            "required": true,
            "description": "The event id (UUIDv7), the same on every attempt and replay: deduplicate on it.",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "webhook-timestamp",
            "in": "header",
            "required": true,
            "description": "Unix time (seconds) of this attempt. Refuse values more than 5 minutes from your clock.",
            "schema": {
              "type": "string",
              "pattern": "^\\d+$"
            }
          },
          {
            "name": "webhook-signature",
            "in": "header",
            "required": true,
            "description": "Space-separated `v1,<base64>` signatures: HMAC-SHA256 of `<webhook-id>.<webhook-timestamp>.<body>` with the base64-decoded part of the whsec_ secret. Accept the request if any of them matches (there is one per valid secret during a rotation).",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "oneOf": [
                  {
                    "$ref": "#/components/schemas/DocumentEvent"
                  },
                  {
                    "$ref": "#/components/schemas/EventThin"
                  }
                ]
              }
            }
          }
        },
        "responses": {
          "2XX": {
            "description": "Acknowledged. Anything else is retried."
          }
        }
      }
    },
    "purchase_settlement.authorized": {
      "post": {
        "operationId": "webhookPurchaseSettlementAuthorized",
        "summary": "purchase_settlement.authorized",
        "description": "The SRI authorized the document.",
        "tags": [
          "Webhooks"
        ],
        "parameters": [
          {
            "name": "webhook-id",
            "in": "header",
            "required": true,
            "description": "The event id (UUIDv7), the same on every attempt and replay: deduplicate on it.",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "webhook-timestamp",
            "in": "header",
            "required": true,
            "description": "Unix time (seconds) of this attempt. Refuse values more than 5 minutes from your clock.",
            "schema": {
              "type": "string",
              "pattern": "^\\d+$"
            }
          },
          {
            "name": "webhook-signature",
            "in": "header",
            "required": true,
            "description": "Space-separated `v1,<base64>` signatures: HMAC-SHA256 of `<webhook-id>.<webhook-timestamp>.<body>` with the base64-decoded part of the whsec_ secret. Accept the request if any of them matches (there is one per valid secret during a rotation).",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "oneOf": [
                  {
                    "$ref": "#/components/schemas/DocumentEvent"
                  },
                  {
                    "$ref": "#/components/schemas/EventThin"
                  }
                ]
              }
            }
          }
        },
        "responses": {
          "2XX": {
            "description": "Acknowledged. Anything else is retried."
          }
        }
      }
    },
    "purchase_settlement.rejected": {
      "post": {
        "operationId": "webhookPurchaseSettlementRejected",
        "summary": "purchase_settlement.rejected",
        "description": "The SRI rejected the document (see sriMessages).",
        "tags": [
          "Webhooks"
        ],
        "parameters": [
          {
            "name": "webhook-id",
            "in": "header",
            "required": true,
            "description": "The event id (UUIDv7), the same on every attempt and replay: deduplicate on it.",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "webhook-timestamp",
            "in": "header",
            "required": true,
            "description": "Unix time (seconds) of this attempt. Refuse values more than 5 minutes from your clock.",
            "schema": {
              "type": "string",
              "pattern": "^\\d+$"
            }
          },
          {
            "name": "webhook-signature",
            "in": "header",
            "required": true,
            "description": "Space-separated `v1,<base64>` signatures: HMAC-SHA256 of `<webhook-id>.<webhook-timestamp>.<body>` with the base64-decoded part of the whsec_ secret. Accept the request if any of them matches (there is one per valid secret during a rotation).",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "oneOf": [
                  {
                    "$ref": "#/components/schemas/DocumentEvent"
                  },
                  {
                    "$ref": "#/components/schemas/EventThin"
                  }
                ]
              }
            }
          }
        },
        "responses": {
          "2XX": {
            "description": "Acknowledged. Anything else is retried."
          }
        }
      }
    },
    "credit_note.authorized": {
      "post": {
        "operationId": "webhookCreditNoteAuthorized",
        "summary": "credit_note.authorized",
        "description": "The SRI authorized the document.",
        "tags": [
          "Webhooks"
        ],
        "parameters": [
          {
            "name": "webhook-id",
            "in": "header",
            "required": true,
            "description": "The event id (UUIDv7), the same on every attempt and replay: deduplicate on it.",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "webhook-timestamp",
            "in": "header",
            "required": true,
            "description": "Unix time (seconds) of this attempt. Refuse values more than 5 minutes from your clock.",
            "schema": {
              "type": "string",
              "pattern": "^\\d+$"
            }
          },
          {
            "name": "webhook-signature",
            "in": "header",
            "required": true,
            "description": "Space-separated `v1,<base64>` signatures: HMAC-SHA256 of `<webhook-id>.<webhook-timestamp>.<body>` with the base64-decoded part of the whsec_ secret. Accept the request if any of them matches (there is one per valid secret during a rotation).",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "oneOf": [
                  {
                    "$ref": "#/components/schemas/DocumentEvent"
                  },
                  {
                    "$ref": "#/components/schemas/EventThin"
                  }
                ]
              }
            }
          }
        },
        "responses": {
          "2XX": {
            "description": "Acknowledged. Anything else is retried."
          }
        }
      }
    },
    "credit_note.rejected": {
      "post": {
        "operationId": "webhookCreditNoteRejected",
        "summary": "credit_note.rejected",
        "description": "The SRI rejected the document (see sriMessages).",
        "tags": [
          "Webhooks"
        ],
        "parameters": [
          {
            "name": "webhook-id",
            "in": "header",
            "required": true,
            "description": "The event id (UUIDv7), the same on every attempt and replay: deduplicate on it.",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "webhook-timestamp",
            "in": "header",
            "required": true,
            "description": "Unix time (seconds) of this attempt. Refuse values more than 5 minutes from your clock.",
            "schema": {
              "type": "string",
              "pattern": "^\\d+$"
            }
          },
          {
            "name": "webhook-signature",
            "in": "header",
            "required": true,
            "description": "Space-separated `v1,<base64>` signatures: HMAC-SHA256 of `<webhook-id>.<webhook-timestamp>.<body>` with the base64-decoded part of the whsec_ secret. Accept the request if any of them matches (there is one per valid secret during a rotation).",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "oneOf": [
                  {
                    "$ref": "#/components/schemas/DocumentEvent"
                  },
                  {
                    "$ref": "#/components/schemas/EventThin"
                  }
                ]
              }
            }
          }
        },
        "responses": {
          "2XX": {
            "description": "Acknowledged. Anything else is retried."
          }
        }
      }
    },
    "debit_note.authorized": {
      "post": {
        "operationId": "webhookDebitNoteAuthorized",
        "summary": "debit_note.authorized",
        "description": "The SRI authorized the document.",
        "tags": [
          "Webhooks"
        ],
        "parameters": [
          {
            "name": "webhook-id",
            "in": "header",
            "required": true,
            "description": "The event id (UUIDv7), the same on every attempt and replay: deduplicate on it.",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "webhook-timestamp",
            "in": "header",
            "required": true,
            "description": "Unix time (seconds) of this attempt. Refuse values more than 5 minutes from your clock.",
            "schema": {
              "type": "string",
              "pattern": "^\\d+$"
            }
          },
          {
            "name": "webhook-signature",
            "in": "header",
            "required": true,
            "description": "Space-separated `v1,<base64>` signatures: HMAC-SHA256 of `<webhook-id>.<webhook-timestamp>.<body>` with the base64-decoded part of the whsec_ secret. Accept the request if any of them matches (there is one per valid secret during a rotation).",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "oneOf": [
                  {
                    "$ref": "#/components/schemas/DocumentEvent"
                  },
                  {
                    "$ref": "#/components/schemas/EventThin"
                  }
                ]
              }
            }
          }
        },
        "responses": {
          "2XX": {
            "description": "Acknowledged. Anything else is retried."
          }
        }
      }
    },
    "debit_note.rejected": {
      "post": {
        "operationId": "webhookDebitNoteRejected",
        "summary": "debit_note.rejected",
        "description": "The SRI rejected the document (see sriMessages).",
        "tags": [
          "Webhooks"
        ],
        "parameters": [
          {
            "name": "webhook-id",
            "in": "header",
            "required": true,
            "description": "The event id (UUIDv7), the same on every attempt and replay: deduplicate on it.",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "webhook-timestamp",
            "in": "header",
            "required": true,
            "description": "Unix time (seconds) of this attempt. Refuse values more than 5 minutes from your clock.",
            "schema": {
              "type": "string",
              "pattern": "^\\d+$"
            }
          },
          {
            "name": "webhook-signature",
            "in": "header",
            "required": true,
            "description": "Space-separated `v1,<base64>` signatures: HMAC-SHA256 of `<webhook-id>.<webhook-timestamp>.<body>` with the base64-decoded part of the whsec_ secret. Accept the request if any of them matches (there is one per valid secret during a rotation).",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "oneOf": [
                  {
                    "$ref": "#/components/schemas/DocumentEvent"
                  },
                  {
                    "$ref": "#/components/schemas/EventThin"
                  }
                ]
              }
            }
          }
        },
        "responses": {
          "2XX": {
            "description": "Acknowledged. Anything else is retried."
          }
        }
      }
    },
    "waybill.authorized": {
      "post": {
        "operationId": "webhookWaybillAuthorized",
        "summary": "waybill.authorized",
        "description": "The SRI authorized the document.",
        "tags": [
          "Webhooks"
        ],
        "parameters": [
          {
            "name": "webhook-id",
            "in": "header",
            "required": true,
            "description": "The event id (UUIDv7), the same on every attempt and replay: deduplicate on it.",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "webhook-timestamp",
            "in": "header",
            "required": true,
            "description": "Unix time (seconds) of this attempt. Refuse values more than 5 minutes from your clock.",
            "schema": {
              "type": "string",
              "pattern": "^\\d+$"
            }
          },
          {
            "name": "webhook-signature",
            "in": "header",
            "required": true,
            "description": "Space-separated `v1,<base64>` signatures: HMAC-SHA256 of `<webhook-id>.<webhook-timestamp>.<body>` with the base64-decoded part of the whsec_ secret. Accept the request if any of them matches (there is one per valid secret during a rotation).",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "oneOf": [
                  {
                    "$ref": "#/components/schemas/DocumentEvent"
                  },
                  {
                    "$ref": "#/components/schemas/EventThin"
                  }
                ]
              }
            }
          }
        },
        "responses": {
          "2XX": {
            "description": "Acknowledged. Anything else is retried."
          }
        }
      }
    },
    "waybill.rejected": {
      "post": {
        "operationId": "webhookWaybillRejected",
        "summary": "waybill.rejected",
        "description": "The SRI rejected the document (see sriMessages).",
        "tags": [
          "Webhooks"
        ],
        "parameters": [
          {
            "name": "webhook-id",
            "in": "header",
            "required": true,
            "description": "The event id (UUIDv7), the same on every attempt and replay: deduplicate on it.",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "webhook-timestamp",
            "in": "header",
            "required": true,
            "description": "Unix time (seconds) of this attempt. Refuse values more than 5 minutes from your clock.",
            "schema": {
              "type": "string",
              "pattern": "^\\d+$"
            }
          },
          {
            "name": "webhook-signature",
            "in": "header",
            "required": true,
            "description": "Space-separated `v1,<base64>` signatures: HMAC-SHA256 of `<webhook-id>.<webhook-timestamp>.<body>` with the base64-decoded part of the whsec_ secret. Accept the request if any of them matches (there is one per valid secret during a rotation).",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "oneOf": [
                  {
                    "$ref": "#/components/schemas/DocumentEvent"
                  },
                  {
                    "$ref": "#/components/schemas/EventThin"
                  }
                ]
              }
            }
          }
        },
        "responses": {
          "2XX": {
            "description": "Acknowledged. Anything else is retried."
          }
        }
      }
    },
    "withholding.authorized": {
      "post": {
        "operationId": "webhookWithholdingAuthorized",
        "summary": "withholding.authorized",
        "description": "The SRI authorized the document.",
        "tags": [
          "Webhooks"
        ],
        "parameters": [
          {
            "name": "webhook-id",
            "in": "header",
            "required": true,
            "description": "The event id (UUIDv7), the same on every attempt and replay: deduplicate on it.",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "webhook-timestamp",
            "in": "header",
            "required": true,
            "description": "Unix time (seconds) of this attempt. Refuse values more than 5 minutes from your clock.",
            "schema": {
              "type": "string",
              "pattern": "^\\d+$"
            }
          },
          {
            "name": "webhook-signature",
            "in": "header",
            "required": true,
            "description": "Space-separated `v1,<base64>` signatures: HMAC-SHA256 of `<webhook-id>.<webhook-timestamp>.<body>` with the base64-decoded part of the whsec_ secret. Accept the request if any of them matches (there is one per valid secret during a rotation).",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "oneOf": [
                  {
                    "$ref": "#/components/schemas/DocumentEvent"
                  },
                  {
                    "$ref": "#/components/schemas/EventThin"
                  }
                ]
              }
            }
          }
        },
        "responses": {
          "2XX": {
            "description": "Acknowledged. Anything else is retried."
          }
        }
      }
    },
    "withholding.rejected": {
      "post": {
        "operationId": "webhookWithholdingRejected",
        "summary": "withholding.rejected",
        "description": "The SRI rejected the document (see sriMessages).",
        "tags": [
          "Webhooks"
        ],
        "parameters": [
          {
            "name": "webhook-id",
            "in": "header",
            "required": true,
            "description": "The event id (UUIDv7), the same on every attempt and replay: deduplicate on it.",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "webhook-timestamp",
            "in": "header",
            "required": true,
            "description": "Unix time (seconds) of this attempt. Refuse values more than 5 minutes from your clock.",
            "schema": {
              "type": "string",
              "pattern": "^\\d+$"
            }
          },
          {
            "name": "webhook-signature",
            "in": "header",
            "required": true,
            "description": "Space-separated `v1,<base64>` signatures: HMAC-SHA256 of `<webhook-id>.<webhook-timestamp>.<body>` with the base64-decoded part of the whsec_ secret. Accept the request if any of them matches (there is one per valid secret during a rotation).",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "oneOf": [
                  {
                    "$ref": "#/components/schemas/DocumentEvent"
                  },
                  {
                    "$ref": "#/components/schemas/EventThin"
                  }
                ]
              }
            }
          }
        },
        "responses": {
          "2XX": {
            "description": "Acknowledged. Anything else is retried."
          }
        }
      }
    },
    "certificate.verified": {
      "post": {
        "operationId": "webhookCertificateVerified",
        "summary": "certificate.verified",
        "description": "The certificate was verified not revoked: when it is accepted, or when a pending status is verified.",
        "tags": [
          "Webhooks"
        ],
        "parameters": [
          {
            "name": "webhook-id",
            "in": "header",
            "required": true,
            "description": "The event id (UUIDv7), the same on every attempt and replay: deduplicate on it.",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "webhook-timestamp",
            "in": "header",
            "required": true,
            "description": "Unix time (seconds) of this attempt. Refuse values more than 5 minutes from your clock.",
            "schema": {
              "type": "string",
              "pattern": "^\\d+$"
            }
          },
          {
            "name": "webhook-signature",
            "in": "header",
            "required": true,
            "description": "Space-separated `v1,<base64>` signatures: HMAC-SHA256 of `<webhook-id>.<webhook-timestamp>.<body>` with the base64-decoded part of the whsec_ secret. Accept the request if any of them matches (there is one per valid secret during a rotation).",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "oneOf": [
                  {
                    "$ref": "#/components/schemas/CertificateEvent"
                  },
                  {
                    "$ref": "#/components/schemas/EventThin"
                  }
                ]
              }
            }
          }
        },
        "responses": {
          "2XX": {
            "description": "Acknowledged. Anything else is retried."
          }
        }
      }
    },
    "certificate.pending": {
      "post": {
        "operationId": "webhookCertificatePending",
        "summary": "certificate.pending",
        "description": "The revocation status could not be verified: the certificate signs until revocation.blockAt. Raised again with each reminder.",
        "tags": [
          "Webhooks"
        ],
        "parameters": [
          {
            "name": "webhook-id",
            "in": "header",
            "required": true,
            "description": "The event id (UUIDv7), the same on every attempt and replay: deduplicate on it.",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "webhook-timestamp",
            "in": "header",
            "required": true,
            "description": "Unix time (seconds) of this attempt. Refuse values more than 5 minutes from your clock.",
            "schema": {
              "type": "string",
              "pattern": "^\\d+$"
            }
          },
          {
            "name": "webhook-signature",
            "in": "header",
            "required": true,
            "description": "Space-separated `v1,<base64>` signatures: HMAC-SHA256 of `<webhook-id>.<webhook-timestamp>.<body>` with the base64-decoded part of the whsec_ secret. Accept the request if any of them matches (there is one per valid secret during a rotation).",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "oneOf": [
                  {
                    "$ref": "#/components/schemas/CertificateEvent"
                  },
                  {
                    "$ref": "#/components/schemas/EventThin"
                  }
                ]
              }
            }
          }
        },
        "responses": {
          "2XX": {
            "description": "Acknowledged. Anything else is retried."
          }
        }
      }
    },
    "certificate.blocked": {
      "post": {
        "operationId": "webhookCertificateBlocked",
        "summary": "certificate.blocked",
        "description": "The certificate stopped signing: still unverified at blockAt, or its chain is no longer trusted.",
        "tags": [
          "Webhooks"
        ],
        "parameters": [
          {
            "name": "webhook-id",
            "in": "header",
            "required": true,
            "description": "The event id (UUIDv7), the same on every attempt and replay: deduplicate on it.",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "webhook-timestamp",
            "in": "header",
            "required": true,
            "description": "Unix time (seconds) of this attempt. Refuse values more than 5 minutes from your clock.",
            "schema": {
              "type": "string",
              "pattern": "^\\d+$"
            }
          },
          {
            "name": "webhook-signature",
            "in": "header",
            "required": true,
            "description": "Space-separated `v1,<base64>` signatures: HMAC-SHA256 of `<webhook-id>.<webhook-timestamp>.<body>` with the base64-decoded part of the whsec_ secret. Accept the request if any of them matches (there is one per valid secret during a rotation).",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "oneOf": [
                  {
                    "$ref": "#/components/schemas/CertificateEvent"
                  },
                  {
                    "$ref": "#/components/schemas/EventThin"
                  }
                ]
              }
            }
          }
        },
        "responses": {
          "2XX": {
            "description": "Acknowledged. Anything else is retried."
          }
        }
      }
    },
    "certificate.revoked": {
      "post": {
        "operationId": "webhookCertificateRevoked",
        "summary": "certificate.revoked",
        "description": "The certification authority revoked the certificate; it never signs again.",
        "tags": [
          "Webhooks"
        ],
        "parameters": [
          {
            "name": "webhook-id",
            "in": "header",
            "required": true,
            "description": "The event id (UUIDv7), the same on every attempt and replay: deduplicate on it.",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "webhook-timestamp",
            "in": "header",
            "required": true,
            "description": "Unix time (seconds) of this attempt. Refuse values more than 5 minutes from your clock.",
            "schema": {
              "type": "string",
              "pattern": "^\\d+$"
            }
          },
          {
            "name": "webhook-signature",
            "in": "header",
            "required": true,
            "description": "Space-separated `v1,<base64>` signatures: HMAC-SHA256 of `<webhook-id>.<webhook-timestamp>.<body>` with the base64-decoded part of the whsec_ secret. Accept the request if any of them matches (there is one per valid secret during a rotation).",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "oneOf": [
                  {
                    "$ref": "#/components/schemas/CertificateEvent"
                  },
                  {
                    "$ref": "#/components/schemas/EventThin"
                  }
                ]
              }
            }
          }
        },
        "responses": {
          "2XX": {
            "description": "Acknowledged. Anything else is retried."
          }
        }
      }
    },
    "certificate.reactivated": {
      "post": {
        "operationId": "webhookCertificateReactivated",
        "summary": "certificate.reactivated",
        "description": "A blocked certificate was verified good and signs again.",
        "tags": [
          "Webhooks"
        ],
        "parameters": [
          {
            "name": "webhook-id",
            "in": "header",
            "required": true,
            "description": "The event id (UUIDv7), the same on every attempt and replay: deduplicate on it.",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "webhook-timestamp",
            "in": "header",
            "required": true,
            "description": "Unix time (seconds) of this attempt. Refuse values more than 5 minutes from your clock.",
            "schema": {
              "type": "string",
              "pattern": "^\\d+$"
            }
          },
          {
            "name": "webhook-signature",
            "in": "header",
            "required": true,
            "description": "Space-separated `v1,<base64>` signatures: HMAC-SHA256 of `<webhook-id>.<webhook-timestamp>.<body>` with the base64-decoded part of the whsec_ secret. Accept the request if any of them matches (there is one per valid secret during a rotation).",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "oneOf": [
                  {
                    "$ref": "#/components/schemas/CertificateEvent"
                  },
                  {
                    "$ref": "#/components/schemas/EventThin"
                  }
                ]
              }
            }
          }
        },
        "responses": {
          "2XX": {
            "description": "Acknowledged. Anything else is retried."
          }
        }
      }
    },
    "document.ride.generated": {
      "post": {
        "operationId": "webhookDocumentRideGenerated",
        "summary": "document.ride.generated",
        "description": "The RIDE (PDF) of the authorized document was generated.",
        "tags": [
          "Webhooks"
        ],
        "parameters": [
          {
            "name": "webhook-id",
            "in": "header",
            "required": true,
            "description": "The event id (UUIDv7), the same on every attempt and replay: deduplicate on it.",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "webhook-timestamp",
            "in": "header",
            "required": true,
            "description": "Unix time (seconds) of this attempt. Refuse values more than 5 minutes from your clock.",
            "schema": {
              "type": "string",
              "pattern": "^\\d+$"
            }
          },
          {
            "name": "webhook-signature",
            "in": "header",
            "required": true,
            "description": "Space-separated `v1,<base64>` signatures: HMAC-SHA256 of `<webhook-id>.<webhook-timestamp>.<body>` with the base64-decoded part of the whsec_ secret. Accept the request if any of them matches (there is one per valid secret during a rotation).",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "oneOf": [
                  {
                    "$ref": "#/components/schemas/DocumentEvent"
                  },
                  {
                    "$ref": "#/components/schemas/EventThin"
                  }
                ]
              }
            }
          }
        },
        "responses": {
          "2XX": {
            "description": "Acknowledged. Anything else is retried."
          }
        }
      }
    },
    "document.ride.failed": {
      "post": {
        "operationId": "webhookDocumentRideFailed",
        "summary": "document.ride.failed",
        "description": "The RIDE (PDF) could not be generated.",
        "tags": [
          "Webhooks"
        ],
        "parameters": [
          {
            "name": "webhook-id",
            "in": "header",
            "required": true,
            "description": "The event id (UUIDv7), the same on every attempt and replay: deduplicate on it.",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "webhook-timestamp",
            "in": "header",
            "required": true,
            "description": "Unix time (seconds) of this attempt. Refuse values more than 5 minutes from your clock.",
            "schema": {
              "type": "string",
              "pattern": "^\\d+$"
            }
          },
          {
            "name": "webhook-signature",
            "in": "header",
            "required": true,
            "description": "Space-separated `v1,<base64>` signatures: HMAC-SHA256 of `<webhook-id>.<webhook-timestamp>.<body>` with the base64-decoded part of the whsec_ secret. Accept the request if any of them matches (there is one per valid secret during a rotation).",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "oneOf": [
                  {
                    "$ref": "#/components/schemas/DocumentEvent"
                  },
                  {
                    "$ref": "#/components/schemas/EventThin"
                  }
                ]
              }
            }
          }
        },
        "responses": {
          "2XX": {
            "description": "Acknowledged. Anything else is retried."
          }
        }
      }
    },
    "document.email.sent": {
      "post": {
        "operationId": "webhookDocumentEmailSent",
        "summary": "document.email.sent",
        "description": "The email to the buyer was sent.",
        "tags": [
          "Webhooks"
        ],
        "parameters": [
          {
            "name": "webhook-id",
            "in": "header",
            "required": true,
            "description": "The event id (UUIDv7), the same on every attempt and replay: deduplicate on it.",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "webhook-timestamp",
            "in": "header",
            "required": true,
            "description": "Unix time (seconds) of this attempt. Refuse values more than 5 minutes from your clock.",
            "schema": {
              "type": "string",
              "pattern": "^\\d+$"
            }
          },
          {
            "name": "webhook-signature",
            "in": "header",
            "required": true,
            "description": "Space-separated `v1,<base64>` signatures: HMAC-SHA256 of `<webhook-id>.<webhook-timestamp>.<body>` with the base64-decoded part of the whsec_ secret. Accept the request if any of them matches (there is one per valid secret during a rotation).",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "oneOf": [
                  {
                    "$ref": "#/components/schemas/DocumentEvent"
                  },
                  {
                    "$ref": "#/components/schemas/EventThin"
                  }
                ]
              }
            }
          }
        },
        "responses": {
          "2XX": {
            "description": "Acknowledged. Anything else is retried."
          }
        }
      }
    },
    "document.email.delivered": {
      "post": {
        "operationId": "webhookDocumentEmailDelivered",
        "summary": "document.email.delivered",
        "description": "The buyer's mail server accepted the email.",
        "tags": [
          "Webhooks"
        ],
        "parameters": [
          {
            "name": "webhook-id",
            "in": "header",
            "required": true,
            "description": "The event id (UUIDv7), the same on every attempt and replay: deduplicate on it.",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "webhook-timestamp",
            "in": "header",
            "required": true,
            "description": "Unix time (seconds) of this attempt. Refuse values more than 5 minutes from your clock.",
            "schema": {
              "type": "string",
              "pattern": "^\\d+$"
            }
          },
          {
            "name": "webhook-signature",
            "in": "header",
            "required": true,
            "description": "Space-separated `v1,<base64>` signatures: HMAC-SHA256 of `<webhook-id>.<webhook-timestamp>.<body>` with the base64-decoded part of the whsec_ secret. Accept the request if any of them matches (there is one per valid secret during a rotation).",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "oneOf": [
                  {
                    "$ref": "#/components/schemas/DocumentEvent"
                  },
                  {
                    "$ref": "#/components/schemas/EventThin"
                  }
                ]
              }
            }
          }
        },
        "responses": {
          "2XX": {
            "description": "Acknowledged. Anything else is retried."
          }
        }
      }
    },
    "document.email.bounced": {
      "post": {
        "operationId": "webhookDocumentEmailBounced",
        "summary": "document.email.bounced",
        "description": "The email bounced.",
        "tags": [
          "Webhooks"
        ],
        "parameters": [
          {
            "name": "webhook-id",
            "in": "header",
            "required": true,
            "description": "The event id (UUIDv7), the same on every attempt and replay: deduplicate on it.",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "webhook-timestamp",
            "in": "header",
            "required": true,
            "description": "Unix time (seconds) of this attempt. Refuse values more than 5 minutes from your clock.",
            "schema": {
              "type": "string",
              "pattern": "^\\d+$"
            }
          },
          {
            "name": "webhook-signature",
            "in": "header",
            "required": true,
            "description": "Space-separated `v1,<base64>` signatures: HMAC-SHA256 of `<webhook-id>.<webhook-timestamp>.<body>` with the base64-decoded part of the whsec_ secret. Accept the request if any of them matches (there is one per valid secret during a rotation).",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "oneOf": [
                  {
                    "$ref": "#/components/schemas/DocumentEvent"
                  },
                  {
                    "$ref": "#/components/schemas/EventThin"
                  }
                ]
              }
            }
          }
        },
        "responses": {
          "2XX": {
            "description": "Acknowledged. Anything else is retried."
          }
        }
      }
    },
    "document.email.complained": {
      "post": {
        "operationId": "webhookDocumentEmailComplained",
        "summary": "document.email.complained",
        "description": "The recipient marked the email as spam.",
        "tags": [
          "Webhooks"
        ],
        "parameters": [
          {
            "name": "webhook-id",
            "in": "header",
            "required": true,
            "description": "The event id (UUIDv7), the same on every attempt and replay: deduplicate on it.",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "webhook-timestamp",
            "in": "header",
            "required": true,
            "description": "Unix time (seconds) of this attempt. Refuse values more than 5 minutes from your clock.",
            "schema": {
              "type": "string",
              "pattern": "^\\d+$"
            }
          },
          {
            "name": "webhook-signature",
            "in": "header",
            "required": true,
            "description": "Space-separated `v1,<base64>` signatures: HMAC-SHA256 of `<webhook-id>.<webhook-timestamp>.<body>` with the base64-decoded part of the whsec_ secret. Accept the request if any of them matches (there is one per valid secret during a rotation).",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "oneOf": [
                  {
                    "$ref": "#/components/schemas/DocumentEvent"
                  },
                  {
                    "$ref": "#/components/schemas/EventThin"
                  }
                ]
              }
            }
          }
        },
        "responses": {
          "2XX": {
            "description": "Acknowledged. Anything else is retried."
          }
        }
      }
    },
    "document.email.failed": {
      "post": {
        "operationId": "webhookDocumentEmailFailed",
        "summary": "document.email.failed",
        "description": "The email could not be sent.",
        "tags": [
          "Webhooks"
        ],
        "parameters": [
          {
            "name": "webhook-id",
            "in": "header",
            "required": true,
            "description": "The event id (UUIDv7), the same on every attempt and replay: deduplicate on it.",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "webhook-timestamp",
            "in": "header",
            "required": true,
            "description": "Unix time (seconds) of this attempt. Refuse values more than 5 minutes from your clock.",
            "schema": {
              "type": "string",
              "pattern": "^\\d+$"
            }
          },
          {
            "name": "webhook-signature",
            "in": "header",
            "required": true,
            "description": "Space-separated `v1,<base64>` signatures: HMAC-SHA256 of `<webhook-id>.<webhook-timestamp>.<body>` with the base64-decoded part of the whsec_ secret. Accept the request if any of them matches (there is one per valid secret during a rotation).",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "oneOf": [
                  {
                    "$ref": "#/components/schemas/DocumentEvent"
                  },
                  {
                    "$ref": "#/components/schemas/EventThin"
                  }
                ]
              }
            }
          }
        },
        "responses": {
          "2XX": {
            "description": "Acknowledged. Anything else is retried."
          }
        }
      }
    },
    "account.email_paused": {
      "post": {
        "operationId": "webhookAccountEmailPaused",
        "summary": "account.email_paused",
        "description": "The account's buyer emails of this mode were paused: too many hard bounces or complaints in the last 7 days, or by Flashpi's staff. Documents are still issued; their emails fail with email_sending_paused until Flashpi's staff resume them.",
        "tags": [
          "Webhooks"
        ],
        "parameters": [
          {
            "name": "webhook-id",
            "in": "header",
            "required": true,
            "description": "The event id (UUIDv7), the same on every attempt and replay: deduplicate on it.",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "webhook-timestamp",
            "in": "header",
            "required": true,
            "description": "Unix time (seconds) of this attempt. Refuse values more than 5 minutes from your clock.",
            "schema": {
              "type": "string",
              "pattern": "^\\d+$"
            }
          },
          {
            "name": "webhook-signature",
            "in": "header",
            "required": true,
            "description": "Space-separated `v1,<base64>` signatures: HMAC-SHA256 of `<webhook-id>.<webhook-timestamp>.<body>` with the base64-decoded part of the whsec_ secret. Accept the request if any of them matches (there is one per valid secret during a rotation).",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "oneOf": [
                  {
                    "$ref": "#/components/schemas/AccountEvent"
                  },
                  {
                    "$ref": "#/components/schemas/EventThin"
                  }
                ]
              }
            }
          }
        },
        "responses": {
          "2XX": {
            "description": "Acknowledged. Anything else is retried."
          }
        }
      }
    },
    "account.email_resumed": {
      "post": {
        "operationId": "webhookAccountEmailResumed",
        "summary": "account.email_resumed",
        "description": "Flashpi's staff resumed the account's buyer emails of this mode.",
        "tags": [
          "Webhooks"
        ],
        "parameters": [
          {
            "name": "webhook-id",
            "in": "header",
            "required": true,
            "description": "The event id (UUIDv7), the same on every attempt and replay: deduplicate on it.",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "webhook-timestamp",
            "in": "header",
            "required": true,
            "description": "Unix time (seconds) of this attempt. Refuse values more than 5 minutes from your clock.",
            "schema": {
              "type": "string",
              "pattern": "^\\d+$"
            }
          },
          {
            "name": "webhook-signature",
            "in": "header",
            "required": true,
            "description": "Space-separated `v1,<base64>` signatures: HMAC-SHA256 of `<webhook-id>.<webhook-timestamp>.<body>` with the base64-decoded part of the whsec_ secret. Accept the request if any of them matches (there is one per valid secret during a rotation).",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "oneOf": [
                  {
                    "$ref": "#/components/schemas/AccountEvent"
                  },
                  {
                    "$ref": "#/components/schemas/EventThin"
                  }
                ]
              }
            }
          }
        },
        "responses": {
          "2XX": {
            "description": "Acknowledged. Anything else is retried."
          }
        }
      }
    },
    "webhook_endpoint.verification": {
      "post": {
        "operationId": "webhookWebhookEndpointVerification",
        "summary": "webhook_endpoint.verification",
        "description": "The activation handshake of an endpoint, sent when it is created, when its URL changes and on POST /v1/webhook-endpoints/{id}/verify; every attempt has a new id and challenge. It is signed like every webhook; answer 2xx with `{\"challenge\": \"<data.challenge>\"}` (or the challenge as plain text).",
        "tags": [
          "Webhooks"
        ],
        "parameters": [
          {
            "name": "webhook-id",
            "in": "header",
            "required": true,
            "description": "The id of this handshake attempt (UUIDv7), also the body `id`: new on every attempt and not an event (GET /v1/events does not know it). It only enters the signature.",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "webhook-timestamp",
            "in": "header",
            "required": true,
            "description": "Unix time (seconds) of this attempt. Refuse values more than 5 minutes from your clock.",
            "schema": {
              "type": "string",
              "pattern": "^\\d+$"
            }
          },
          {
            "name": "webhook-signature",
            "in": "header",
            "required": true,
            "description": "Space-separated `v1,<base64>` signatures: HMAC-SHA256 of `<webhook-id>.<webhook-timestamp>.<body>` with the base64-decoded part of the whsec_ secret. Accept the request if any of them matches (there is one per valid secret during a rotation).",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/WebhookEndpointVerificationEvent"
              }
            }
          }
        },
        "responses": {
          "2XX": {
            "description": "The challenge, echoed.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "challenge"
                  ],
                  "properties": {
                    "challenge": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          }
        }
      }
    }
  }
}
