{
  "openapi": "3.1.0",
  "info": {
    "title": "Modelvia client management API",
    "version": "2026-09-24",
    "description": "Client-management only, after operator-assisted onboarding. Excludes inference, member sessions, operator controls and identity bridges. Inference uses a separate project key: https://modelvia.dev/docs/first-call. Fictional examples require your agreed models/caps and do not activate terms. Billing/invoice responses intentionally describe verified projection fields only. Nano-AUD is an integer string: 1 AUD = 1,000,000,000 nano-AUD; cents fields are different."
  },
  "servers": [
    {
      "url": "https://api.modelvia.dev"
    }
  ],
  "security": [
    {
      "ClientIntegrationKey": []
    }
  ],
  "tags": [
    {
      "name": "Customers"
    },
    {
      "name": "Project keys"
    },
    {
      "name": "Customer console"
    },
    {
      "name": "Payments"
    }
  ],
  "paths": {
    "/v1/client/customers": {
      "get": {
        "operationId": "list_customers",
        "tags": [
          "Customers"
        ],
        "summary": "List customers",
        "description": "Returns only customers of the authenticated client.",
        "responses": {
          "200": {
            "description": "Success. Creates return 200, including identical account retries.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "customers": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/Customer"
                      }
                    }
                  },
                  "required": [
                    "customers"
                  ]
                }
              }
            }
          },
          "default": {
            "description": "Refusal as {error:code}. 400 invalid request; 401 invalid key; 403 scope/inactive; 404 missing scoped resource; 409 conflict/reconciliation; 413 read bound; 429 rate limit (Retry-After); 5xx unavailable/uncertain. Timeout does not prove no mutation.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      },
      "post": {
        "operationId": "create_customer",
        "tags": [
          "Customers"
        ],
        "summary": "Create customer",
        "description": "Requires pre-arranged client billing ownership. No version/billingCompanyId accepted. Prefix your IDs. Caps/concurrency/models narrow the client.",
        "responses": {
          "200": {
            "description": "Success. Creates return 200, including identical account retries.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Customer"
                }
              }
            }
          },
          "default": {
            "description": "Refusal as {error:code}. 400 invalid request; 401 invalid key; 403 scope/inactive; 404 missing scoped resource; 409 conflict/reconciliation; 413 read bound; 429 rate limit (Retry-After); 5xx unavailable/uncertain. Timeout does not prove no mutation.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CustomerCreate"
              }
            }
          }
        },
        "x-retry-semantics": "identical_body_returns_existing; changed_body_409; no_update"
      }
    },
    "/v1/client/customers/{customer}/projects": {
      "post": {
        "operationId": "create_project",
        "tags": [
          "Customers"
        ],
        "summary": "Create project",
        "description": "Requires your own customer with your client as payer. Customer-paid billing needs operator assistance. Child narrows parent; request cap cannot exceed monthly cap.",
        "responses": {
          "200": {
            "description": "Success. Creates return 200, including identical account retries.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Project"
                }
              }
            }
          },
          "default": {
            "description": "Refusal as {error:code}. 400 invalid request; 401 invalid key; 403 scope/inactive; 404 missing scoped resource; 409 conflict/reconciliation; 413 read bound; 429 rate limit (Retry-After); 5xx unavailable/uncertain. Timeout does not prove no mutation.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ProjectCreate"
              }
            }
          }
        },
        "x-retry-semantics": "identical_body_returns_existing; changed_body_409; no_update",
        "parameters": [
          {
            "name": "customer",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[A-Za-z0-9_.-]+$",
              "maxLength": 160
            }
          }
        ]
      }
    },
    "/v1/client/customers/{customer}/projects/{project}/keys": {
      "get": {
        "operationId": "list_project_keys",
        "tags": [
          "Project keys"
        ],
        "summary": "List project keys",
        "description": "Metadata only, never secrets. Includes revoked/expired keys; check timestamps and environment.",
        "responses": {
          "200": {
            "description": "Success. Creates return 200, including identical account retries.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "keys": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/ProjectKey"
                      }
                    }
                  },
                  "required": [
                    "keys"
                  ]
                }
              }
            }
          },
          "default": {
            "description": "Refusal as {error:code}. 400 invalid request; 401 invalid key; 403 scope/inactive; 404 missing scoped resource; 409 conflict/reconciliation; 413 read bound; 429 rate limit (Retry-After); 5xx unavailable/uncertain. Timeout does not prove no mutation.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "customer",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[A-Za-z0-9_.-]+$",
              "maxLength": 160
            }
          },
          {
            "name": "project",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[A-Za-z0-9_.-]+$",
              "maxLength": 160
            }
          }
        ]
      },
      "post": {
        "operationId": "mint_project_key",
        "tags": [
          "Project keys"
        ],
        "summary": "Mint project key",
        "description": "Active ancestry, permitted environment and active unexpired client-paid billing service required. At most 100 active keys per client. Secret shown once. Serialize key issuance; list/reconcile after an unknown result.",
        "responses": {
          "200": {
            "description": "Success. Creates return 200, including identical account retries.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/KeyIssued"
                }
              }
            }
          },
          "default": {
            "description": "Refusal as {error:code}. 400 invalid request; 401 invalid key; 403 scope/inactive; 404 missing scoped resource; 409 conflict/reconciliation; 413 read bound; 429 rate limit (Retry-After); 5xx unavailable/uncertain. Timeout does not prove no mutation.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/KeyCreate"
              }
            }
          }
        },
        "x-retry-semantics": "non_idempotent; repeated_post_mints_another_key; no_Idempotency-Key_guard",
        "parameters": [
          {
            "name": "customer",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[A-Za-z0-9_.-]+$",
              "maxLength": 160
            }
          },
          {
            "name": "project",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[A-Za-z0-9_.-]+$",
              "maxLength": 160
            }
          }
        ]
      }
    },
    "/v1/client/customers/{customer}/projects/{project}/keys/{key}/rotate": {
      "post": {
        "operationId": "rotate_project_key",
        "tags": [
          "Project keys"
        ],
        "summary": "Rotate project key",
        "description": "No request fields. Issues a new secret and revokes the old key. After an unknown result, list and reconcile before another mutation.",
        "responses": {
          "200": {
            "description": "Success. Creates return 200, including identical account retries.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/KeyIssued"
                }
              }
            }
          },
          "default": {
            "description": "Refusal as {error:code}. 400 invalid request; 401 invalid key; 403 scope/inactive; 404 missing scoped resource; 409 conflict/reconciliation; 413 read bound; 429 rate limit (Retry-After); 5xx unavailable/uncertain. Timeout does not prove no mutation.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "x-retry-semantics": "non_replayable_secret; repeated_original_key_returns_409_key_revoked; no_Idempotency-Key_response_replay; reconcile_unknown_outcome_before_new_issuance",
        "parameters": [
          {
            "name": "customer",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[A-Za-z0-9_.-]+$",
              "maxLength": 160
            }
          },
          {
            "name": "project",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[A-Za-z0-9_.-]+$",
              "maxLength": 160
            }
          },
          {
            "name": "key",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[a-f0-9]{16}$",
              "maxLength": 160
            }
          }
        ]
      }
    },
    "/v1/client/customers/{customer}/projects/{project}/keys/{key}/revoke": {
      "post": {
        "operationId": "revoke_project_key",
        "tags": [
          "Project keys"
        ],
        "summary": "Revoke project key",
        "description": "No request fields. Only this scoped project key. Repeating preserves revokedAt.",
        "responses": {
          "200": {
            "description": "Success. Creates return 200, including identical account retries.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProjectKey"
                }
              }
            }
          },
          "default": {
            "description": "Refusal as {error:code}. 400 invalid request; 401 invalid key; 403 scope/inactive; 404 missing scoped resource; 409 conflict/reconciliation; 413 read bound; 429 rate limit (Retry-After); 5xx unavailable/uncertain. Timeout does not prove no mutation.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "x-retry-semantics": "idempotent; preserves_revokedAt",
        "parameters": [
          {
            "name": "customer",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[A-Za-z0-9_.-]+$",
              "maxLength": 160
            }
          },
          {
            "name": "project",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[A-Za-z0-9_.-]+$",
              "maxLength": 160
            }
          },
          {
            "name": "key",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[a-f0-9]{16}$",
              "maxLength": 160
            }
          }
        ]
      }
    },
    "/v1/client/customers/{customer}/usage-summary": {
      "get": {
        "operationId": "read_customer_usage",
        "tags": [
          "Customer console"
        ],
        "summary": "Read customer usage",
        "description": "Customer-safe totals independent of invoices. Null means unknown. Sums the whole month at any volume; there is no request count that refuses the read. Retain request binding: response has no customerId.",
        "responses": {
          "200": {
            "description": "Success. Creates return 200, including identical account retries.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/UsageSummary"
                }
              }
            }
          },
          "default": {
            "description": "Refusal as {error:code}. 400 invalid request; 401 invalid key; 403 scope/inactive; 404 missing scoped resource; 409 conflict/reconciliation; 413 read bound; 429 rate limit (Retry-After); 5xx unavailable/uncertain. Timeout does not prove no mutation.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "customer",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[A-Za-z0-9_.-]+$",
              "maxLength": 160
            }
          },
          {
            "name": "period",
            "in": "query",
            "schema": {
              "type": "string",
              "pattern": "^20[0-9]{2}-(0[1-9]|1[0-2])$"
            },
            "description": "At most one value; no other filters. Defaults to current Brisbane month."
          }
        ]
      }
    },
    "/v1/client/customers/{customer}/billing": {
      "get": {
        "operationId": "read_customer_billing",
        "tags": [
          "Customer console"
        ],
        "summary": "Read customer billing",
        "description": "Check response clientId/customerId against your authenticated server binding. Estimates are not final invoices. Render payment actions only from authoritative flags.",
        "responses": {
          "200": {
            "description": "Success. Creates return 200, including identical account retries.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Billing"
                }
              }
            }
          },
          "default": {
            "description": "Refusal as {error:code}. 400 invalid request; 401 invalid key; 403 scope/inactive; 404 missing scoped resource; 409 conflict/reconciliation; 413 read bound; 429 rate limit (Retry-After); 5xx unavailable/uncertain. Timeout does not prove no mutation.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "customer",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[A-Za-z0-9_.-]+$",
              "maxLength": 160
            }
          },
          {
            "name": "period",
            "in": "query",
            "schema": {
              "type": "string",
              "pattern": "^[0-9]{4}-(0[1-9]|1[0-2])$"
            },
            "description": "Defaults to current Brisbane month."
          }
        ]
      }
    },
    "/v1/client/customers/{customer}/invoices/{invoice}": {
      "get": {
        "operationId": "read_resale_invoice",
        "tags": [
          "Payments"
        ],
        "summary": "Read resale invoice",
        "description": "Issued client resale invoice plus payment state. Platform-billed invoices use a separate portal contract, not this resale-document route.",
        "responses": {
          "200": {
            "description": "Success. Creates return 200, including identical account retries.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "default": {
            "description": "Refusal as {error:code}. 400 invalid request; 401 invalid key; 403 scope/inactive; 404 missing scoped resource; 409 conflict/reconciliation; 413 read bound; 429 rate limit (Retry-After); 5xx unavailable/uncertain. Timeout does not prove no mutation.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "customer",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[A-Za-z0-9_.-]+$",
              "maxLength": 160
            }
          },
          {
            "name": "invoice",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[A-Za-z0-9-]+$",
              "maxLength": 160
            }
          }
        ]
      }
    },
    "/v1/client/customers/{customer}/invoices/{invoice}/document": {
      "get": {
        "operationId": "read_resale_invoice_document",
        "tags": [
          "Payments"
        ],
        "summary": "Read resale invoice document",
        "description": "Issued scoped resale invoice as HTML; display in a sandboxed document surface.",
        "responses": {
          "200": {
            "description": "Invoice HTML.",
            "content": {
              "text/html": {
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "default": {
            "description": "Refusal as {error:code}. 400 invalid request; 401 invalid key; 403 scope/inactive; 404 missing scoped resource; 409 conflict/reconciliation; 413 read bound; 429 rate limit (Retry-After); 5xx unavailable/uncertain. Timeout does not prove no mutation.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "customer",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[A-Za-z0-9_.-]+$",
              "maxLength": 160
            }
          },
          {
            "name": "invoice",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[A-Za-z0-9-]+$",
              "maxLength": 160
            }
          }
        ]
      }
    },
    "/v1/client/customers/{customer}/invoices/{invoice}/checkout": {
      "post": {
        "operationId": "start_invoice_checkout",
        "tags": [
          "Payments"
        ],
        "summary": "Start invoice checkout",
        "description": "No request fields. Authoritative invoice selects amount and seller. Read checkoutAvailable first. Resale uses seller Square merchant; platform payer branch uses separate hosted collection. Unknown outcome holds all payment actions across reload; not_started alone cannot release it.",
        "responses": {
          "200": {
            "description": "Success. Creates return 200, including identical account retries.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Checkout"
                }
              }
            }
          },
          "default": {
            "description": "Refusal as {error:code}. 400 invalid request; 401 invalid key; 403 scope/inactive; 404 missing scoped resource; 409 conflict/reconciliation; 413 read bound; 429 rate limit (Retry-After); 5xx unavailable/uncertain. Timeout does not prove no mutation.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "x-retry-semantics": "reuse_known_ready_link; unknown_outcome_requires_status_or_reconciliation",
        "parameters": [
          {
            "name": "customer",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[A-Za-z0-9_.-]+$",
              "maxLength": 160
            }
          },
          {
            "name": "invoice",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[A-Za-z0-9-]+$",
              "maxLength": 160
            }
          }
        ]
      }
    },
    "/v1/client/customers/{customer}/invoices/{invoice}/external-payment": {
      "post": {
        "operationId": "record_received_direct_payment",
        "tags": [
          "Payments"
        ],
        "summary": "Record received direct payment",
        "description": "Provider bookkeeping; moves no money. Exact full positive issued resale invoice only, direct method permitted, no Square link or credit adjustment. No partial payment, customer self-report or manual refund.",
        "responses": {
          "200": {
            "description": "Success. Creates return 200, including identical account retries.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PaymentSummary"
                }
              }
            }
          },
          "default": {
            "description": "Refusal as {error:code}. 400 invalid request; 401 invalid key; 403 scope/inactive; 404 missing scoped resource; 409 conflict/reconciliation; 413 read bound; 429 rate limit (Retry-After); 5xx unavailable/uncertain. Timeout does not prove no mutation.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ExternalPayment"
              }
            }
          }
        },
        "x-retry-semantics": "identical_receipt_idempotent; conflicting_receipt_409",
        "parameters": [
          {
            "name": "customer",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[A-Za-z0-9_.-]+$",
              "maxLength": 160
            }
          },
          {
            "name": "invoice",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[A-Za-z0-9-]+$",
              "maxLength": 160
            }
          }
        ]
      }
    },
    "/v1/client/payment-settings": {
      "get": {
        "operationId": "read_payment_methods",
        "tags": [
          "Payments"
        ],
        "summary": "Read payment methods",
        "description": "Methods differ from checkout surface. Square configured does not mean live money movement.",
        "responses": {
          "200": {
            "description": "Success. Creates return 200, including identical account retries.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PaymentSettings"
                }
              }
            }
          },
          "default": {
            "description": "Refusal as {error:code}. 400 invalid request; 401 invalid key; 403 scope/inactive; 404 missing scoped resource; 409 conflict/reconciliation; 413 read bound; 429 rate limit (Retry-After); 5xx unavailable/uncertain. Timeout does not prove no mutation.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      },
      "post": {
        "operationId": "set_payment_methods",
        "tags": [
          "Payments"
        ],
        "summary": "Set payment methods",
        "description": "clientId asserts authenticated provider, never selects scope. Current version required. Read back after conflict/unknown result before retry. Trusted server credential, not a member-session MFA contract.",
        "responses": {
          "200": {
            "description": "Success. Creates return 200, including identical account retries.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PaymentSettings"
                }
              }
            }
          },
          "default": {
            "description": "Refusal as {error:code}. 400 invalid request; 401 invalid key; 403 scope/inactive; 404 missing scoped resource; 409 conflict/reconciliation; 413 read bound; 429 rate limit (Retry-After); 5xx unavailable/uncertain. Timeout does not prove no mutation.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/PaymentSettingsWrite"
              }
            }
          }
        },
        "x-retry-semantics": "versioned_write; read_back_after_conflict_or_unknown"
      }
    },
    "/v1/client/charge-detail": {
      "get": {
        "operationId": "read_customer_charge_detail",
        "tags": [
          "Payments"
        ],
        "summary": "Read what customers are shown of each charge",
        "description": "all_in (default) shows end customers one AI usage amount; itemized splits the same amount into model usage, routing and service fee. You always see the full breakdown on your own Modelvia invoices.",
        "responses": {
          "200": {
            "description": "Success.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ChargeDetailSettings"
                }
              }
            }
          },
          "default": {
            "description": "Refusal as {error:code}. 400 invalid request; 401 invalid key; 403 scope/inactive; 404 missing scoped resource; 409 conflict/reconciliation; 413 read bound; 429 rate limit (Retry-After); 5xx unavailable/uncertain. Timeout does not prove no mutation.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      },
      "post": {
        "operationId": "set_customer_charge_detail",
        "tags": [
          "Payments"
        ],
        "summary": "Set what customers are shown of each charge",
        "description": "clientId asserts the authenticated client, never selects scope. Current version required; 409 account_version_conflict or charge_detail_scope_changed means read back before retrying. Presentation only: no price, total or issued invoice changes.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ChargeDetailWrite"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Success.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ChargeDetailSettings"
                }
              }
            }
          },
          "default": {
            "description": "Refusal as {error:code}. 400 invalid request; 401 invalid key; 403 scope/inactive; 404 missing scoped resource; 409 conflict/reconciliation; 413 read bound; 429 rate limit (Retry-After); 5xx unavailable/uncertain. Timeout does not prove no mutation.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "x-retry-semantics": "versioned_write; read_back_after_conflict_or_unknown"
      }
    }
  },
  "components": {
    "securitySchemes": {
      "ClientIntegrationKey": {
        "type": "http",
        "scheme": "bearer",
        "bearerFormat": "mgt_<id>_<secret>",
        "description": "Modelvia-provisioned client key. Backend only; powerful management credential, never a customer login or inference key."
      }
    },
    "schemas": {
      "Error": {
        "type": "object",
        "properties": {
          "error": {
            "type": "string"
          }
        },
        "required": [
          "error"
        ]
      },
      "CustomerCreate": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "pattern": "^[a-zA-Z0-9][a-zA-Z0-9_.-]{0,159}$",
            "description": "Use this URL-safe subset for customer/project IDs. Slash and colon IDs cannot be addressed by these client routes."
          },
          "name": {
            "type": "string",
            "minLength": 1,
            "maxLength": 200,
            "pattern": "\\S"
          },
          "active": {
            "type": "boolean"
          },
          "monthlyCapNanoAud": {
            "type": "string",
            "pattern": "^(0|[1-9][0-9]{0,20})$"
          },
          "maxConcurrent": {
            "type": "integer",
            "minimum": 1,
            "maximum": 100
          },
          "allowedModels": {
            "type": "array",
            "items": {
              "type": "string",
              "pattern": "^[a-zA-Z0-9][a-zA-Z0-9_.:/-]{0,159}$"
            },
            "minItems": 1,
            "maxItems": 64,
            "uniqueItems": true
          },
          "clientId": {
            "type": "string",
            "pattern": "^[a-zA-Z0-9][a-zA-Z0-9_.:/-]{0,159}$"
          },
          "payer": {
            "enum": [
              "client"
            ],
            "description": "Only for mixed billing where this client pays. Omit otherwise."
          }
        },
        "required": [
          "id",
          "name",
          "active",
          "monthlyCapNanoAud",
          "maxConcurrent",
          "allowedModels"
        ],
        "additionalProperties": false,
        "example": {
          "id": "exampleco-customer-001",
          "name": "ExampleCo sample customer",
          "active": true,
          "monthlyCapNanoAud": "50000000000",
          "maxConcurrent": 2,
          "allowedModels": [
            "example-vendor/example-model"
          ]
        }
      },
      "ProjectCreate": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "pattern": "^[a-zA-Z0-9][a-zA-Z0-9_.-]{0,159}$",
            "description": "Use this URL-safe subset for customer/project IDs. Slash and colon IDs cannot be addressed by these client routes."
          },
          "name": {
            "type": "string",
            "minLength": 1,
            "maxLength": 200,
            "pattern": "\\S"
          },
          "active": {
            "type": "boolean"
          },
          "monthlyCapNanoAud": {
            "type": "string",
            "pattern": "^(0|[1-9][0-9]{0,20})$"
          },
          "maxConcurrent": {
            "type": "integer",
            "minimum": 1,
            "maximum": 100
          },
          "allowedModels": {
            "type": "array",
            "items": {
              "type": "string",
              "pattern": "^[a-zA-Z0-9][a-zA-Z0-9_.:/-]{0,159}$"
            },
            "minItems": 1,
            "maxItems": 64,
            "uniqueItems": true
          },
          "clientId": {
            "type": "string",
            "pattern": "^[a-zA-Z0-9][a-zA-Z0-9_.:/-]{0,159}$"
          },
          "customerId": {
            "type": "string",
            "pattern": "^[a-zA-Z0-9][a-zA-Z0-9_.:/-]{0,159}$"
          },
          "environments": {
            "type": "array",
            "items": {
              "type": "string",
              "pattern": "^[a-zA-Z0-9][a-zA-Z0-9_.:/-]{0,159}$"
            },
            "minItems": 1,
            "maxItems": 64,
            "uniqueItems": true
          },
          "requestCapNanoAud": {
            "type": "string",
            "pattern": "^(0|[1-9][0-9]{0,20})$"
          }
        },
        "required": [
          "id",
          "name",
          "active",
          "monthlyCapNanoAud",
          "maxConcurrent",
          "allowedModels",
          "environments",
          "requestCapNanoAud"
        ],
        "additionalProperties": false,
        "example": {
          "id": "exampleco-project-001",
          "name": "ExampleCo sample project",
          "active": true,
          "monthlyCapNanoAud": "10000000000",
          "maxConcurrent": 1,
          "allowedModels": [
            "example-vendor/example-model"
          ],
          "environments": [
            "development"
          ],
          "requestCapNanoAud": "100000000"
        }
      },
      "Customer": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "pattern": "^[a-zA-Z0-9][a-zA-Z0-9_.:/-]{0,159}$"
          },
          "name": {
            "type": "string",
            "minLength": 1,
            "maxLength": 200,
            "pattern": "\\S"
          },
          "active": {
            "type": "boolean"
          },
          "monthlyCapNanoAud": {
            "type": "string",
            "pattern": "^(0|[1-9][0-9]{0,20})$"
          },
          "maxConcurrent": {
            "type": "integer",
            "minimum": 1,
            "maximum": 100
          },
          "allowedModels": {
            "type": "array",
            "items": {
              "type": "string",
              "pattern": "^[a-zA-Z0-9][a-zA-Z0-9_.:/-]{0,159}$"
            },
            "minItems": 1,
            "maxItems": 64,
            "uniqueItems": true
          },
          "clientId": {
            "type": "string",
            "pattern": "^[a-zA-Z0-9][a-zA-Z0-9_.:/-]{0,159}$"
          },
          "payer": {
            "type": "string",
            "enum": [
              "client",
              "customer"
            ],
            "description": "For mixed billing, the authoritative payer assigned to this customer."
          },
          "version": {
            "type": "integer",
            "minimum": 1,
            "maximum": 9007199254740991
          },
          "billingCompanyId": {
            "type": "string",
            "pattern": "^[a-zA-Z0-9][a-zA-Z0-9_.:/-]{0,159}$"
          }
        },
        "required": [
          "id",
          "name",
          "active",
          "monthlyCapNanoAud",
          "maxConcurrent",
          "allowedModels",
          "clientId",
          "version"
        ]
      },
      "Project": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "pattern": "^[a-zA-Z0-9][a-zA-Z0-9_.:/-]{0,159}$"
          },
          "name": {
            "type": "string",
            "minLength": 1,
            "maxLength": 200,
            "pattern": "\\S"
          },
          "active": {
            "type": "boolean"
          },
          "monthlyCapNanoAud": {
            "type": "string",
            "pattern": "^(0|[1-9][0-9]{0,20})$"
          },
          "maxConcurrent": {
            "type": "integer",
            "minimum": 1,
            "maximum": 100
          },
          "allowedModels": {
            "type": "array",
            "items": {
              "type": "string",
              "pattern": "^[a-zA-Z0-9][a-zA-Z0-9_.:/-]{0,159}$"
            },
            "minItems": 1,
            "maxItems": 64,
            "uniqueItems": true
          },
          "clientId": {
            "type": "string",
            "pattern": "^[a-zA-Z0-9][a-zA-Z0-9_.:/-]{0,159}$"
          },
          "customerId": {
            "type": "string",
            "pattern": "^[a-zA-Z0-9][a-zA-Z0-9_.:/-]{0,159}$"
          },
          "environments": {
            "type": "array",
            "items": {
              "type": "string",
              "pattern": "^[a-zA-Z0-9][a-zA-Z0-9_.:/-]{0,159}$"
            },
            "minItems": 1,
            "maxItems": 64,
            "uniqueItems": true
          },
          "requestCapNanoAud": {
            "type": "string",
            "pattern": "^(0|[1-9][0-9]{0,20})$"
          },
          "version": {
            "type": "integer",
            "minimum": 1,
            "maximum": 9007199254740991
          }
        },
        "required": [
          "id",
          "name",
          "active",
          "monthlyCapNanoAud",
          "maxConcurrent",
          "allowedModels",
          "clientId",
          "customerId",
          "environments",
          "requestCapNanoAud",
          "version"
        ]
      },
      "ProjectKey": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "pattern": "^[a-f0-9]{16}$"
          },
          "companyId": {
            "type": "string",
            "pattern": "^[a-zA-Z0-9][a-zA-Z0-9_.:/-]{0,159}$"
          },
          "project": {
            "type": "string",
            "pattern": "^[a-zA-Z0-9][a-zA-Z0-9_.:/-]{0,159}$"
          },
          "environment": {
            "type": "string",
            "pattern": "^[a-zA-Z0-9][a-zA-Z0-9_.:/-]{0,159}$"
          },
          "label": {
            "type": "string"
          },
          "createdAt": {
            "type": "integer"
          },
          "expiresAt": {
            "type": "integer"
          },
          "revokedAt": {
            "type": "integer"
          },
          "lastUsedAt": {
            "type": "integer"
          }
        },
        "required": [
          "id",
          "companyId",
          "project",
          "environment",
          "createdAt"
        ]
      },
      "KeyCreate": {
        "type": "object",
        "properties": {
          "environment": {
            "type": "string",
            "pattern": "^[a-zA-Z0-9][a-zA-Z0-9_.:/-]{0,159}$"
          },
          "label": {
            "type": "string",
            "minLength": 1,
            "maxLength": 200
          }
        },
        "required": [
          "environment"
        ],
        "additionalProperties": false,
        "example": {
          "environment": "development",
          "label": "ExampleCo server"
        }
      },
      "KeyIssued": {
        "type": "object",
        "properties": {
          "key": {
            "type": "string",
            "description": "Secret shown once; store securely. Never log it or expose it to a customer browser."
          },
          "record": {
            "$ref": "#/components/schemas/ProjectKey"
          },
          "replaced": {
            "type": "string",
            "description": "Previous key id on rotation."
          }
        },
        "required": [
          "key",
          "record"
        ]
      },
      "CustomerPayment": {
        "type": "object",
        "properties": {
          "methods": {
            "enum": [
              "square",
              "direct",
              "both",
              "disabled"
            ]
          },
          "directInstructions": {
            "type": "string",
            "pattern": "^[^<>\\u0000-\\u0008\\u000b\\u000c\\u000e-\\u001f\\u007f]*$",
            "description": "Optional for square/disabled, required for direct/both. When supplied, trimmed value must be nonblank and at most 2000 characters. Tab/newline/carriage-return allowed; HTML angle brackets and other control characters refused.",
            "minLength": 1,
            "x-max-trimmed-length": 2000,
            "allOf": [
              {
                "pattern": "\\S"
              }
            ]
          }
        },
        "required": [
          "methods"
        ],
        "additionalProperties": false,
        "allOf": [
          {
            "if": {
              "properties": {
                "methods": {
                  "enum": [
                    "direct",
                    "both"
                  ]
                }
              }
            },
            "then": {
              "required": [
                "directInstructions"
              ],
              "properties": {
                "directInstructions": {
                  "minLength": 1
                }
              }
            }
          }
        ]
      },
      "PaymentSettingsWrite": {
        "type": "object",
        "properties": {
          "clientId": {
            "type": "string",
            "pattern": "^[a-zA-Z0-9][a-zA-Z0-9_.:/-]{0,159}$"
          },
          "version": {
            "type": "integer",
            "minimum": 0,
            "maximum": 9007199254740991
          },
          "customerPayment": {
            "$ref": "#/components/schemas/CustomerPayment"
          }
        },
        "required": [
          "clientId",
          "version",
          "customerPayment"
        ],
        "additionalProperties": false
      },
      "PaymentSettings": {
        "type": "object",
        "properties": {
          "clientId": {
            "type": "string",
            "pattern": "^[a-zA-Z0-9][a-zA-Z0-9_.:/-]{0,159}$"
          },
          "version": {
            "type": "integer",
            "minimum": 1,
            "maximum": 9007199254740991
          },
          "customerPayment": {
            "$ref": "#/components/schemas/CustomerPayment"
          },
          "squareConfigured": {
            "type": "boolean"
          },
          "paymentMode": {
            "enum": [
              "sandbox",
              "live",
              "disabled"
            ]
          }
        },
        "required": [
          "clientId",
          "version",
          "customerPayment",
          "squareConfigured",
          "paymentMode"
        ]
      },
      "ExternalPayment": {
        "type": "object",
        "properties": {
          "reference": {
            "type": "string",
            "minLength": 1,
            "pattern": "^[^<>\\u0000-\\u001f\\u007f]+$",
            "description": "Trimmed nonblank statement reference, at most 200 characters; no control characters or angle brackets. Unique within this client.",
            "x-max-trimmed-length": 200,
            "allOf": [
              {
                "pattern": "\\S"
              }
            ]
          },
          "amountCents": {
            "type": "string",
            "pattern": "^[1-9][0-9]{0,20}$",
            "description": "Full exact positive invoice amount in AUD cents."
          },
          "currency": {
            "const": "AUD"
          },
          "receivedAt": {
            "type": "string",
            "format": "date-time",
            "description": "Canonical UTC ISO timestamp, no later than server time."
          }
        },
        "required": [
          "reference",
          "amountCents",
          "currency",
          "receivedAt"
        ],
        "additionalProperties": false,
        "example": {
          "reference": "exampleco-bank-reference-001",
          "amountCents": "2500",
          "currency": "AUD",
          "receivedAt": "2026-09-01T00:00:00.000Z"
        }
      },
      "PaymentSummary": {
        "type": "object",
        "properties": {
          "mode": {
            "enum": [
              "sandbox",
              "live",
              "disabled"
            ]
          },
          "paid": {
            "type": "boolean"
          },
          "refundedCents": {
            "type": "string",
            "pattern": "^[0-9]+$"
          },
          "paymentState": {
            "type": "string"
          },
          "collectionEnabled": {
            "type": "boolean"
          },
          "checkoutAvailable": {
            "type": "boolean"
          },
          "directPaymentAvailable": {
            "type": "boolean"
          },
          "externalPaymentRecordable": {
            "type": "boolean"
          },
          "sellerName": {
            "type": "string"
          },
          "receipt": {
            "type": "object",
            "properties": {
              "source": {
                "enum": [
                  "square",
                  "external"
                ]
              },
              "invoice": {
                "type": "string"
              },
              "amountCents": {
                "type": "string",
                "pattern": "^[0-9]+$"
              },
              "currency": {
                "const": "AUD"
              },
              "settledAt": {
                "type": "string",
                "format": "date-time"
              },
              "paymentId": {
                "type": "string",
                "description": "Square receipts only."
              }
            },
            "required": [
              "source",
              "invoice",
              "amountCents",
              "currency",
              "settledAt"
            ]
          }
        },
        "required": [
          "mode",
          "paid",
          "refundedCents",
          "paymentState",
          "collectionEnabled",
          "checkoutAvailable",
          "directPaymentAvailable",
          "externalPaymentRecordable",
          "sellerName"
        ]
      },
      "UsageSummary": {
        "type": "object",
        "properties": {
          "period": {
            "type": "string"
          },
          "requests": {
            "type": "integer",
            "minimum": 0
          },
          "tokens": {
            "type": "object",
            "properties": {
              "input": {
                "type": "string",
                "pattern": "^[0-9]+$"
              },
              "output": {
                "type": "string",
                "pattern": "^[0-9]+$"
              }
            },
            "required": [
              "input",
              "output"
            ]
          },
          "money": {
            "type": "object",
            "properties": {
              "customerNetNanoAud": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "itemized": {
                "type": [
                  "object",
                  "null"
                ],
                "description": "Present only when the client itemizes: modelUsage + routing + serviceFee - credits = customerNetNanoAud. null when a price is unknown.",
                "properties": {
                  "modelUsageNanoAud": {
                    "type": "string",
                    "pattern": "^[0-9]+$"
                  },
                  "routingNanoAud": {
                    "type": "string",
                    "pattern": "^[0-9]+$"
                  },
                  "serviceFeeNanoAud": {
                    "type": "string",
                    "pattern": "^[0-9]+$"
                  },
                  "creditsNanoAud": {
                    "type": "string",
                    "pattern": "^[0-9]+$"
                  }
                },
                "required": [
                  "modelUsageNanoAud",
                  "routingNanoAud",
                  "serviceFeeNanoAud",
                  "creditsNanoAud"
                ]
              }
            },
            "required": [
              "customerNetNanoAud"
            ]
          },
          "monthlyCapNanoAud": {
            "type": "string",
            "pattern": "^[0-9]+$"
          },
          "remainingNanoAud": {
            "type": [
              "string",
              "null"
            ]
          },
          "budgetUsed": {
            "type": [
              "object",
              "null"
            ],
            "description": "What the cap counts: chargedNanoAud + clientFundedNanoAud + pendingNanoAud = monthlyCapNanoAud - remainingNanoAud before the floor at 0. clientFunded is usage the client covers (customer net 0). null exactly when remainingNanoAud is null. Absent from older gateways.",
            "properties": {
              "chargedNanoAud": {
                "type": "string",
                "pattern": "^[0-9]+$"
              },
              "clientFundedNanoAud": {
                "type": "string",
                "pattern": "^[0-9]+$"
              },
              "pendingNanoAud": {
                "type": "string",
                "pattern": "^[0-9]+$"
              }
            },
            "required": [
              "chargedNanoAud",
              "clientFundedNanoAud",
              "pendingNanoAud"
            ]
          },
          "updatedAt": {
            "type": "integer",
            "description": "Epoch milliseconds."
          },
          "chargeDetail": {
            "enum": [
              "all_in",
              "itemized"
            ],
            "description": "The client's customerChargeDetail. Absent from older gateways."
          },
          "usedBy": {
            "$ref": "#/components/schemas/UsedBy"
          }
        },
        "required": [
          "period",
          "requests",
          "tokens",
          "money",
          "monthlyCapNanoAud",
          "remainingNanoAud",
          "updatedAt"
        ]
      },
      "Billing": {
        "type": "object",
        "properties": {
          "clientId": {
            "type": "string",
            "pattern": "^[a-zA-Z0-9][a-zA-Z0-9_.:/-]{0,159}$"
          },
          "customerId": {
            "type": "string",
            "pattern": "^[a-zA-Z0-9][a-zA-Z0-9_.:/-]{0,159}$"
          },
          "period": {
            "type": "string"
          },
          "currency": {
            "const": "AUD"
          },
          "customerCheckout": {
            "enum": [
              "client_app",
              "portal",
              "both",
              "off"
            ]
          },
          "customerPayment": {
            "$ref": "#/components/schemas/CustomerPayment"
          },
          "customerNetNanoAud": {
            "type": [
              "string",
              "null"
            ]
          },
          "usageAvailable": {
            "type": "boolean"
          },
          "collectionEnabled": {
            "type": "boolean"
          },
          "paymentMode": {
            "enum": [
              "sandbox",
              "live",
              "disabled"
            ]
          },
          "invoices": {
            "type": "array",
            "items": {
              "type": "object"
            }
          }
        },
        "required": [
          "clientId",
          "customerId",
          "period",
          "currency",
          "customerCheckout",
          "customerPayment",
          "customerNetNanoAud",
          "usageAvailable",
          "collectionEnabled",
          "paymentMode",
          "invoices"
        ],
        "description": "Verified projection fields only; additional coverage, requests and invoice fields are returned. See customer-console/payments guides. Null money is unknown, never zero."
      },
      "Checkout": {
        "type": "object",
        "properties": {
          "url": {
            "type": "string",
            "format": "uri"
          },
          "sessionId": {
            "type": "string"
          },
          "mode": {
            "enum": [
              "sandbox",
              "live"
            ],
            "description": "Resale Square branch only."
          },
          "expiresAt": {
            "type": "integer",
            "description": "Separately configured platform-billed branch only."
          }
        },
        "required": [
          "url",
          "sessionId"
        ]
      },
      "UsedBy": {
        "description": "Who used an amount: a customer of the client, or the client's own internal use (client-funded terms or unattributed usage).",
        "oneOf": [
          {
            "type": "object",
            "properties": {
              "kind": {
                "const": "customer"
              },
              "customerId": {
                "type": "string"
              },
              "displayName": {
                "type": "string"
              },
              "projectId": {
                "type": [
                  "string",
                  "null"
                ]
              }
            },
            "required": [
              "kind",
              "customerId",
              "displayName",
              "projectId"
            ]
          },
          {
            "type": "object",
            "properties": {
              "kind": {
                "const": "client_internal"
              },
              "clientId": {
                "type": "string"
              },
              "displayName": {
                "type": "string"
              }
            },
            "required": [
              "kind",
              "clientId",
              "displayName"
            ]
          }
        ]
      },
      "ChargeDetailSettings": {
        "type": "object",
        "description": "What this client's end customers are shown of each charge. all_in (default): one AI usage amount. itemized: the same amount split into model usage, routing and service fee. Presentation only; totals never change.",
        "properties": {
          "clientId": {
            "type": "string",
            "pattern": "^[a-zA-Z0-9][a-zA-Z0-9_.:/-]{0,159}$"
          },
          "version": {
            "type": "integer",
            "minimum": 1,
            "maximum": 9007199254740991
          },
          "customerChargeDetail": {
            "enum": [
              "all_in",
              "itemized"
            ]
          }
        },
        "required": [
          "clientId",
          "version",
          "customerChargeDetail"
        ]
      },
      "ChargeDetailWrite": {
        "type": "object",
        "properties": {
          "clientId": {
            "type": "string",
            "pattern": "^[a-zA-Z0-9][a-zA-Z0-9_.:/-]{0,159}$"
          },
          "version": {
            "type": "integer",
            "minimum": 0,
            "maximum": 9007199254740991
          },
          "customerChargeDetail": {
            "enum": [
              "all_in",
              "itemized"
            ]
          }
        },
        "required": [
          "clientId",
          "version",
          "customerChargeDetail"
        ],
        "additionalProperties": false,
        "example": {
          "clientId": "example-client",
          "version": 1,
          "customerChargeDetail": "itemized"
        }
      }
    }
  }
}
