---
title: "Mint a persistent API key via x402 USDC payment"
method: POST
path: "/v5/x402/mint"
tags: ["Billing"]
---

# Mint a persistent API key via x402 USDC payment

`POST /v5/x402/mint`

## Request

- Base URL: `https://headlessoracle.com`
- URL: `https://headlessoracle.com/v5/x402/mint`
- Auth: none declared

Agents submit a verified Base mainnet USDC transaction hash and receive a persistent ho_live_ API key. Builder tier: 99 USDC = 50K calls/day. Pro tier: 299 USDC = 200K calls/day. Each tx_hash mints at most one key: the hash is claimed atomically before the key is created. The request must carry `signature`, an EIP-191 personal_sign by the address that sent the USDC Transfer over the exact message "headlessoracle.com x402 mint <tx_hash>" (tx_hash lowercase); it is checked before the hash is claimed, so a wrong signature cannot spend the payer's claim. Only an EOA can mint: smart-contract wallets (ERC-1271) are not supported.

## Request body

- object
  - `tx_hash` string, required: Base mainnet USDC transaction hash (0x-prefixed).
  - `tier` 'builder' | 'pro', required: Desired key tier.
  - `signature` string, required: Payer binding. EIP-191 personal_sign (keccak256("\x19Ethereum Signed Message:\n" + byte length + message)) by the address that sent the USDC Transfer, as 65 bytes of 0x-prefixed hex (r || s || v, v = 27/28 or 0/1). The signer must be an EOA: smart-contract wallets (ERC-1271) are not supported. Message: "headlessoracle.com x402 mint <tx_hash>", with tx_hash lowercase.
  - `network` string: Optional. "base", "base-mainnet" or "eip155:8453".
  - `email` string, email: Optional. The key is returned in the response as api_key.

## Response `200`

Key minted

- object
  - `api_key` string: Your new persistent API key (ho_live_ prefix). Store securely — shown once.
  - `tier` 'builder' | 'pro'
  - `daily_limit` integer

## Other responses

- `400`: BAD_REQUEST (missing tx_hash, bad tier or network), PAYMENT_EXPIRED, PAYER_SIGNATURE_REQUIRED (no signature) or INVALID_PAYER_SIGNATURE (not 65-byte hex, or no signer recovers). The two signature refusals carry message_to_sign and signature_format.
- `402`: PAYMENT_VERIFICATION_FAILED or PAYMENT_INSUFFICIENT: the on-chain USDC transfer could not be verified or is below the tier price.
- `403`: PAYER_MISMATCH: the signature recovers to recovered_address, which is not the Transfer sender (payer_address). No claim is made; the payer can still mint with the hash. Smart-contract wallets (ERC-1271) are not supported.
- `409`: CONFLICT: the transaction hash is already claimed. A hash mints at most one key. claim_status says what became of it (minted, failed, or claimed and in flight); when failed, the body names the contact address.
- `500`: MINT_KEY_NOT_STORED: the payment was received and claimed, but the key could not be stored, so none was issued. Do not pay again or retry; write to the contact address in the body with tx_hash. The operator is alerted.
- `503`: SERVICE_UNAVAILABLE: minting is not configured, or the payment was verified but could not be claimed (detail MINT_CLAIM_STORE_UNAVAILABLE; no key minted, payment not spent; retry after Retry-After).

---

[API](https://skmtc.dev/headlessoracle/apis/headless-oracle.md) · [All operations](https://skmtc.dev/headlessoracle/apis/headless-oracle/llms.txt) · [OpenAPI document](https://skmtc.dev/headlessoracle/apis/headless-oracle/revisions/4e82fe332f29?raw)
