Join our community of builders on Discord!

Accept Per-call Payments

The Developer API takes per-call payments. Your own server can take them too. A facilitator does the payment side for you: it checks each debit authorization and settles it on chain, so your server never sends a payment transaction.
Experimental: the prepaid-debit scheme and the facilitator may change. Per-call payments use the x402 v2 headers with Lightchain AI's own scheme, so standard x402 clients cannot pay them, and standard x402 facilitators cannot settle them.
NetworkFacilitatorSigner (facilitatorAddress)
Testnet (chain 8200)https://x402.testnet.lightchain.ai0xa45CdF29b021c6c5687Ef6A15CB4049b550130E1
Mainnet (chain 9200)https://x402.mainnet.lightchain.ai0x3e84c3957f1752A8e66D33649acCF3a6780C84Cd

What the facilitator does, and what it doesn't

A per-call payment settles by submitting a job: JobRegistry.submitJobWithDebitAuthorization checks the payer's signature, submits the job into a session your server owns, and debits the job's fee from the payer's prepaid balance. The facilitator sends that transaction and pays its gas. Your server still runs the job itself, as for any Lightchain AI job:
  • it owns an active session for the model (it is the payTo of every payment),
  • it encrypts the prompt with that session's key and posts it as an EIP-4844 blob, and
  • it reads the worker's answer and returns it to the caller.
So this suits a server that already runs Lightchain AI jobs and wants its callers to pay for them call by call.

One-time setup

  1. Pick the address that owns your sessions. It is your payTo.
  2. From it, consent to the facilitator once. Settlements for any other payTo are refused on chain.
    CodeBASH
    This spends nothing of your own: the facilitator's allowance on your balance stays 0 unless you raise it, so it can only settle what a payer signed, into your sessions. Revoke it with false.
Your callers need nothing from you beforehand: only a prepaid balance of their own, as described in Payment.

Endpoints

The request and response bodies follow the x402 v2 facilitator API.
Endpoint
GET /supportedThe scheme, network and extra to put in your requirements.
POST /verifyBody {x402Version, paymentPayload, paymentRequirements}. Checks the payment without sending anything: {"isValid":true,"payer":"0x..."}, or {"isValid":false,"invalidReason":"...","payer":"0x..."}.
POST /settleThe same body, with two more fields in paymentRequirements.extra: sessionId (decimal) and blobHash (the prompt blob's versioned hash). It verifies again, then submits the job. It returns {"success":true,"payer":"0x...","transaction":"0x...","network":"eip155:8200","amount":"..."}, where amount is the fee debited, or {"success":false,"errorReason":"...",...}.
GET /health200 while the facilitator can read the chain, 503 when it can't.
CodeBASH
CodeJSON
/verify and /settle answer 200 whatever the decision. An unreadable body gets 400 with reason invalid_payload. The reasons are the ones in the pay-per-call codes, and a few more:
  • invalid_transaction_state: the chain refused the settlement for another reason, such as an inactive session.
  • unexpected_verify_error, unexpected_settle_error: the facilitator could not reach the chain.
    • If the errorMessage of an unexpected_settle_error names a transaction, the settlement was sent but its receipt did not arrive within 60 seconds. It may still land, so look the transaction up before you refuse the call.
A second /settle of the same authorization is refused as invalid_prepaid_debit_payload_nonce_used, even while the first one is still in flight, so a payment is never settled twice. Requests are rate-limited per client IP; over the limit, the answer is 429.

A server that takes a payment

Your server answers 402 with its requirements, verifies the payment the caller retries with, settles it, and then serves. Settling submits the job, so it happens before you answer:
CodeJAVASCRIPT
Verify before you post the blob: a payment that is refused then costs you nothing. The caller signs the payment exactly as for the Developer API: see Sign and send.