On this page
- What do you need before you start?
- Step 1: is the program on, and which pool is it?
- Step 2: how do you delegate to the pool?
- Step 3: how do you request a nonce?
- Step 4: how do you sign the message with CIP-8?
- Step 5: how do you link the wallet?
- Step 6: how do you check the discount balance?
- Step 7: how do you spend it?
- What should you do when a call fails?
- Frequently asked questions
- Sources
To link a Cardano stake address to the Gatewayz API, you ask for a nonce, sign the message it sends back with the stake key using CIP-8, and post the signature and public key back. The whole exchange is two HTTPS calls and one local signature: no transaction, no fee and no deposit. After that, staking rewards from the Gatewayz pool start arriving as an inference discount balance on the account that owns your API key.
What do you need before you start?
You need a Gatewayz API key, a Cardano wallet whose stake key you control, and curl. Set them as environment variables so the examples below run as written.
export GATEWAYZ_API_KEY="..." # your Gatewayz API key; never commit it
export STAKE_ADDRESS="stake1u..." # a key-hash stake address
export API="https://api.gatewayz.ai"The stake address must be a key-hash address. On mainnet those start with stake1u. A script stake address, starting with stake17, is not supported and is rejected with script_stake_address_unsupported. If you have never made an API request before, Your first Gatewayz API request covers keys and headers.
Step 1: is the program on, and which pool is it?
Call GET /delegation/status. It needs no authentication and tells you whether the program is on, the Cardano pool id and network, the reward share, the discount and the disclaimer.
curl -s "$API/delegation/status"The pool id is at data.cardano.pool_id in the response. Until the mainnet pool launches it may be absent; the program is pre-launch and the working demo runs on Cardano's preprod testnet by invitation.
Step 2: how do you delegate to the pool?
You delegate with a normal Cardano delegation transaction, built and signed by your own wallet, pointing your stake key at the pool id from step 1. Gatewayz does not build, sign or see that transaction.
On Cardano, delegating one staking key takes a single transaction containing a delegation certificate and costs only the usual transaction fee. The first time a stake address is registered there is also a one-time stake address deposit, currently 2 ADA, refunded in full when the address is deregistered. Your ADA stays in your wallet and can be spent at any time. Use any wallet or library you trust; the steps below only need the stake address. You can link before or after delegating, but discounts accrue only for epochs in which your stake is active in the pool. How Cardano staking works explains the certificate and the timing.
Step 3: how do you request a nonce?
POST /auth/wallet/cardano/nonce with your stake address and the eligibility attestation. The response is a JSON object with nonce, message and expires_at.
curl -s -X POST "$API/auth/wallet/cardano/nonce" \
-H "Authorization: Bearer $GATEWAYZ_API_KEY" \
-H "Content-Type: application/json" \
-d "{\"stake_address\": \"$STAKE_ADDRESS\", \"not_us_ca_person\": true}"messageis the exact text your wallet must sign. Do not trim, reformat or re-encode it as anything other than its UTF-8 bytes.expires_atis when the nonce stops being accepted. Sign and link before then, or you getnonce_missing_or_expiredand must request a new one.not_us_ca_person: trueis your confirmation that you are not a US or Canadian person. The program is not available to US or Canadian persons.
Step 4: how do you sign the message with CIP-8?
Sign the message bytes with the stake key, producing a COSE_Sign1 signature and a COSE_Key, both hex-encoded. In a browser wallet this is the CIP-30 signData call, which uses CIP-8 under the hood.
// In a page that talks to a CIP-30 wallet (Lace shown; Eternl, Yoroi, VESPR work the same way).
const api = await window.cardano.lace.enable();
// CIP-30 gives addresses as hex-encoded bytes. The first reward address is the stake address.
const [stakeAddressHex] = await api.getRewardAddresses();
// The payload must be hex-encoded bytes: hex of the UTF-8 message from step 3.
const message = nonceResponse.message;
const messageHex = Array.from(new TextEncoder().encode(message))
.map((b) => b.toString(16).padStart(2, "0"))
.join("");
// Signs with the stake key. Resolves to { signature: COSE_Sign1 hex, key: COSE_Key hex }.
const { signature, key } = await api.signData(stakeAddressHex, messageHex);Two details trip people up. First, signData takes the payload as hex-encoded bytes, not as a plain string, so encode the message as UTF-8 and then as hex. Second, CIP-30 passes addresses as hex-encoded bytes; passing the address from getRewardAddresses() tells the wallet to sign with the stake key rather than a payment key. The Gatewayz API expects the bech32 form (stake1u...) in stake_address, which is the same address in a different encoding.
A headless agent without a browser wallet signs the same way with any library that produces a CIP-8 COSE_Sign1 and COSE_Key from its stake signing key. Keep the signing key local to the agent; only the signature and the public COSE_Key leave it.
Step 5: how do you link the wallet?
POST /auth/wallet/cardano/link with the stake address, the signature, the key and the attestation. On success the stake address is linked to the Gatewayz account that owns the API key.
curl -s -X POST "$API/auth/wallet/cardano/link" \
-H "Authorization: Bearer $GATEWAYZ_API_KEY" \
-H "Content-Type: application/json" \
-d "{\"stake_address\": \"$STAKE_ADDRESS\", \"signature\": \"$SIGNATURE_HEX\", \"key\": \"$KEY_HEX\", \"not_us_ca_person\": true}"If you did not send not_us_ca_person in either call, record it separately before any discount is granted:
curl -s -X POST "$API/delegation/eligibility" \
-H "Authorization: Bearer $GATEWAYZ_API_KEY" \
-H "Content-Type: application/json" \
-d '{"not_us_ca_person": true}'Step 6: how do you check the discount balance?
GET /delegation/rewards with your API key. It responds with your linked wallets, measured positions, the discount balance and its history, your eligibility and the disclaimer.
curl -s "$API/delegation/rewards" -H "Authorization: Bearer $GATEWAYZ_API_KEY"Expect an empty history at first. Cardano pays rewards a few epochs after they are earned, so the first discount appears roughly two to three weeks after you first delegate. Polling once a day is enough, since accounting runs daily after a finished epoch is recorded. To recompute any entry yourself from public chain data, see Verify your discount.
Step 7: how do you spend it?
Make inference requests as usual. While the balance lasts, each request through /v1/chat/completions or /v1/messages costs 1% of its list price from your credits, and the other 99% is drawn from the balance.
curl -s "$API/v1/chat/completions" \
-H "Authorization: Bearer $GATEWAYZ_API_KEY" \
-H "Content-Type: application/json" \
-d '{"model": "<model id>", "messages": [{"role": "user", "content": "Hello"}]}'Launch limits: at most $5 of discount per account per day, and at most $50 per day across the whole program. Limits may change.
What should you do when a call fails?
Read the code in the error, not the message text, and follow its remedy. Most link failures mean the signature did not match the issued message or address: request a fresh nonce and sign the exact message again with the right stake key.
Every code, with a decision table for retry, re-sign or stop, is on Errors.
Frequently asked questions
Does linking a stake address cost a fee?
No. Linking is a CIP-8 signed message, not a transaction, so nothing is submitted to the chain and no fee is paid. Only the delegation itself is a transaction, with the usual Cardano fee and, for a stake address that was never registered, the one-time refundable deposit.
Why does signData need hex instead of the message text?
CIP-30 defines the payload of signData as hex-encoded bytes, so wallets sign exactly the bytes you pass. Encode the message from the nonce response as UTF-8, convert those bytes to hex, and pass that string; any other transformation changes the signed payload and the link call fails with payload_mismatch.
Which address do I pass to signData?
Pass the stake (reward) address, which a CIP-30 wallet gives in hex from getRewardAddresses(). Signing with that address makes the wallet use the stake key; signing with a payment address uses a different key and the link call fails with address_mismatch.
How long is a nonce valid?
Until the expires_at time in the nonce response. If you sign or send it after that, the link call fails with nonce_missing_or_expired, and you simply request a new nonce and sign again.
Can I link more than one wallet to an account?
The rewards endpoint reports linked wallets in the plural, so an account can hold several. A single stake address can belong to only one Gatewayz account; linking it to a second account fails with wallet_linked_to_other_account.
Do I have to delegate before linking?
No. You can link before or after delegating. Discounts are only calculated for epochs in which your stake is active in the Gatewayz pool, so linking early does not create a discount by itself.
Sources
- CIP-0008: Message Signing, as of 2026-10-27
- CIP-0030: Cardano dApp-Wallet Web Bridge, as of 2026-10-27
- Cardano Docs: Delegation, as of 2026-10-27
- Cardano.org Glossary: Stake Address Deposit, as of 2026-10-27
- Cardano.org: Stake your ada on Cardano, as of 2026-10-27
Discounts are a share of staking rewards Gatewayz actually received, can change at any time, and are not a guaranteed return. Not available to US or Canadian persons. Every participant must confirm they are not a US or Canadian person before linking a wallet. Not investment, legal or tax advice. Figures as of 2026-10-27. Program disclosures