Jawapan langsung
Halaman ini menerangkan cara pasukan menggunakan gerbang serasi OpenAI NextModel. From per-request billing headers to cryptographic receipts anchored on Base — how to prove what happened, not take it on faith. Ia menambah langkah praktikal, nota konfigurasi, dan soalan lazim.
Three levels of proof
A response can be checked at increasing strength. First, every response carries billing headers: X-NextModel-Billing-Status (settled, rolled_back, or not_charged), X-NextModel-Reservation-Id, and X-NextModel-Failure-Class. These are the gateway's own word about the request — useful inline, and enough to assert that failures never billed. Second, each billable request produces a structured receipt: a canonical JSON record of what was served and what it cost. Third, receipts are anchored — hashed into Merkle batches, the batch manifests written to retention-locked write-once storage, and each batch root anchored on the Base blockchain — so a receipt can be checked independently of the gateway. The headers are convenient; the receipt is evidence.
What a receipt contains
A receipt is deliberately small: enough to reconstruct what happened, never the conversation.
| receipt_id | Stable identifier for the usage record |
| request_id | Gateway request identifier |
| org_public_id | Your account as acct_… — no raw account id in public receipts |
| requested_model / effective_model | The id you asked for and the id that actually served |
| served_mode | How the response was produced (fresh_upstream) |
| usage_source | provider_actual, local_estimated, or cache_replayed |
| billing_basis | fresh_public_price, discounted_cache_price, or byok_management_fee |
| charged_amount / fresh_equivalent_amount | What was billed and what the uncached equivalent would have cost |
| created_at | When the request completed |
Verify a receipt programmatically
POST the three receipt identifiers to the verification endpoint. Verification authenticates with your nextmodel.app dashboard session rather than an API key, and the endpoint lives on the website origin, not the API base URL. A signed-in owner sees the charged amount; an anonymous caller can still verify the hash and anchoring but the charged amount is redacted; a signed-in account that does not own the receipt is refused.
curl -s https://nextmodel.app/v1/receipts/verify \
-H "Content-Type: application/json" \
-d '{"receipt_id": "<receipt_id>", "receipt_hash": "<receipt_hash>", "request_id": "<request_id>"}'Verification outcomes
A 200 response returns the receipt's model and serving facts plus its anchoring statuses (archive_status, anchor_status) and any public anchor events. Everything else is one of:
| 400 receipt_input_required | One of receipt_id, receipt_hash, request_id is missing |
| 403 receipt_forbidden | Receipt belongs to a different signed-in account |
| 404 receipt_not_found | No receipt with that id in the verification window |
| 409 receipt_hash_mismatch | The receipt hash does not match the anchored record — tamper evidence |
| 409 receipt_request_id_mismatch | The request id does not match the receipt |
No-code paths and what mismatch means
The receipt verifier tool at /tools/receipt-verifier accepts the same three values in a form, and the public verifiable-receipts page at /verifiable shows live anchoring status. A hash mismatch is the strong guarantee: receipts are hashed at creation and committed into Merkle batches, so a mismatch means the record changed after issuance — that is the signal auditors act on. For the full anchoring pipeline, see the AI provenance doc.