Sponsored Transactions
Enterprise transaction sponsorship — let your organization pay blockchain fees on behalf of users
Sponsored Transactions
Enterprise transaction sponsorship lets your organization pay the blockchain costs of an Andamio action so the end user never needs ADA in their wallet. This removes the single biggest onboarding barrier for Web3 learning experiences.
Sponsorship is opt-in and tied to an enterprise API key. When a sponsored route is called with an enterprise key that has remaining quota, the Andamio gateway covers the sponsor side of the transaction automatically. No request body changes are required to opt in — the gateway decides based on the key and the route.
Sponsorship is an enterprise feature. Contact the Andamio team to provision sponsorship quota for your API key. Pioneer, Starter, and Growth tiers build self-funded transactions as described in Transaction Handling.
Sponsored Routes
Eight transaction-build routes support sponsorship today, grouped by how quota is counted.
Bootstrap routes (route-scoped quota)
These run before a course_id exists, so quota is counted per route:
| Route | Returns |
|---|---|
POST /api/v2/tx/global/user/access-token/mint | { tx_hash } — submitted for you |
POST /api/v2/tx/instance/owner/course/create | { course_id, unsigned_tx } — holder signs |
Course-bound routes (course-scoped quota)
These act on an existing course, so quota is counted per (api_key, course_id):
| Route | Returns |
|---|---|
POST /api/v2/tx/course/owner/teachers/manage | { unsigned_tx } |
POST /api/v2/tx/course/teacher/modules/manage | { unsigned_tx } |
POST /api/v2/tx/course/teacher/assignments/assess | { unsigned_tx } |
POST /api/v2/tx/course/student/assignment/commit | { unsigned_tx } |
POST /api/v2/tx/course/student/assignment/update | { unsigned_tx } |
POST /api/v2/tx/course/student/credential/claim | { unsigned_tx } |
A typical enterprise lifecycle is: sponsor access-token/mint, then course/create, then downstream course-bound actions against the new course_id.
How a Sponsored Build Differs
When a request qualifies for sponsorship, the gateway:
- Rejects any caller-supplied
sponsor_data. The gateway owns the sponsor configuration — supplying your own is a400. - Resolves quota — by route for bootstrap routes, by
course_idfor course-bound routes. - Builds the transaction with the gateway's sponsor inputs and applies the sponsor signature.
- Returns one of two shapes (see below).
You do not change your request body to request sponsorship. Send the same fields you would for a self-funded build.
Shape 1 — Direct submit (access-token/mint only)
No holder signature is needed, so the gateway submits for you and returns the hash:
{ "tx_hash": "<tx-hash>" }Shape 2 — Holder signs, then submits
Every other sponsored route returns an unsigned transaction (plus course_id for course/create). The holder signs it and submits through the shared sponsored-submit endpoint:
{ "unsigned_tx": "<tx-cbor-hex>" }Submitting a Holder-Signed Sponsored Transaction
After the user signs the returned unsigned_tx, submit it to the shared endpoint. Do not submit it directly to a node — the sponsor signature is merged in by the gateway at submit time.
const API = "https://preprod.api.andamio.io/api/v2";
// 1. Build (sponsored automatically for an enterprise key)
const { unsigned_tx } = await fetch(`${API}/tx/course/student/assignment/commit`, {
method: "POST",
headers: {
"Content-Type": "application/json",
"X-API-Key": ENTERPRISE_API_KEY,
"Authorization": `Bearer ${userJwt}`,
},
body: JSON.stringify({ alias: "student1", course_id: "abc123...", /* ... */ }),
}).then(r => r.json());
// 2. Holder signs in their wallet
const signedTx = await wallet.signTx(unsigned_tx);
// 3. Submit to the shared sponsored endpoint (NOT wallet.submitTx)
const { tx_hash } = await fetch(`${API}/tx/sponsored/submit`, {
method: "POST",
headers: {
"Content-Type": "application/json",
"X-API-Key": ENTERPRISE_API_KEY,
"Authorization": `Bearer ${userJwt}`,
},
body: JSON.stringify({ tx: signedTx }),
}).then(r => r.json());POST /api/v2/tx/sponsored/submit takes { "tx": "<holder-signed-cbor-hex>" } and returns { "tx_hash": "<tx-hash>" }. From there, register and monitor exactly as in Transaction Handling — the lifecycle after submission is identical.
A sponsored build is reserved against quota when it is built. It must be submitted before it expires, or the build is lost and must be rebuilt (and re-counted against quota).
Error Contract
Sponsorship adds a few failure modes on top of the standard transaction errors:
| Status | Meaning |
|---|---|
402 Payment Required | No matching sponsorship allocation, or quota is exhausted. Can also occur at submit time if quota ran out between build and submit. |
400 Bad Request | Caller supplied sponsor_data on a sponsored route, the access-token/mint receiver matched the sponsor address, or the submitted transaction was rejected. |
404 Not Found | No pending sponsored build exists for the submitted transaction. |
409 Conflict | The sponsored build was already submitted. |
410 Gone | The sponsored build expired — rebuild it. |
502 Bad Gateway | The sponsorship or submission service was unavailable. Safe to retry the build. |
Treat 402 as the signal to surface an "out of sponsored capacity" state in your app, and 410 as "rebuild and retry."
Next Steps
- Transaction Handling — The self-funded lifecycle and post-submit monitoring
- API Keys — Enterprise key provisioning
- Billing & Pricing — Tiers and quotas
- Error Handling — Recovery patterns