docs · v0.1-base-sepolia
getting started

What is GlobalAPI?

base sepolia live v0.1 base · usdc

GlobalAPI is a non-custodial API billing platform built on Base. It turns any HTTP endpoint into a paid product in about three minutes — with zero code changes to your upstream service.

If you've built an API and want to charge for it, GlobalAPI handles everything: authentication, per-request metering, USDC settlement, and revenue collection. Payment lands directly in a vault address that only you control — GlobalAPI never touches your funds.

How it works

GlobalAPI sits between callers and your real API as a smart proxy. On every request:

01
caller authenticates & pays

The caller sends a payment authorization alongside the HTTP request. GlobalAPI validates it before forwarding anything upstream.

02
proxy meters & settles on Base

GlobalAPI submits an on-chain transaction, crediting the developer's vault with USDC. Base blocks land in about two seconds, so this completes within the request lifecycle.

03
upstream response forwarded

The caller receives your API's response. Your revenue sits in your vault, ready to sweep anytime. No invoicing. No waiting.

Key concepts

conceptwhat it means
proxy urlYour metered endpoint. Format: <your-globalapi-host>/{user}/{api} — share with callers. Run it locally while the Base Sepolia deployment is being stood up; a hosted domain is TBD.
pda vaultA USDC vault on Base whose address is derived from your wallet address. Payments land there before the vault contract even exists — it is deployed on your first withdrawal. Only you can sweep it.
upstream urlYour real API. GlobalAPI forwards requests here after payment is confirmed. Never exposed to callers.
price / requestUSDC amount a caller pays per proxied request. Set by you, stored on-chain, changeable anytime.
withdraw()The contract call that sweeps your vault revenue to your wallet, minus the platform fee.
Non-custodial guarantee — GlobalAPI never holds your money. Even if we disappear tomorrow, your vault balance remains recoverable on-chain through the factory contract directly.
getting started

Quick Start

Zero to a paid API in under five minutes.

01
sign in to the dashboard

Open the app and connect a Base wallet (MetaMask, Coinbase Wallet, Rainbow) or sign in with email OTP. Signing up costs nothing on-chain: your vault address is derived from your wallet address, and the contract is only deployed when you first withdraw.

02
register & price your API

In the dashboard, click + new api. Enter a name (this becomes part of your proxy URL), the upstream URL GlobalAPI should forward to, and a per-request price in USDC. Set 0 for free-but-metered.

03
share your proxy URL & earn

That's it. The dashboard shows your proxy URL: <your-host>/{username}/{api-name}. Callers pay on every request, you earn automatically. Revenue accrues in your vault — claim it from the dashboard's earnings card whenever you like.

04
SDK roadmap

A first-party SDK (JS, Python, Rust, Go) is planned for v0.2 so you can register and manage APIs from code. The snippet below previews the planned ergonomics — none of these packages resolve yet.

javascript (planned)
import { GlobalAPI } from '@globalapi-sh/sdk'; const client = new GlobalAPI({ privateKey: process.env.GLOBALAPI_PRIVATE_KEY }); const api = await client.register({ name: 'weather', upstream: 'https://weather-service.api.com', pricePerRequest: 0.005, // $0.005 USDC per call description: 'Real-time weather data', }); console.log(api.proxyUrl);
01
fund a Base wallet with USDC

You need an EVM wallet and Base Sepolia USDC. See Wallet & USDC Setup for a step-by-step guide if you're new to Base.

02
use the x402 payment protocol

GlobalAPI authenticates callers via the x402 payment protocol, not API keys. Your client signs a payment payload for each request; the proxy validates and settles it on Base before forwarding upstream. A first call without payment returns 402 Payment Required with the price tag.

03
call any GlobalAPI-proxied API

The reference implementation lives at demo/call.mjs in the repo. Drop in your buyer wallet's private key and you're ready to call paid endpoints:

javascript (node)
import { wrapFetchWithPaymentFromConfig } from '@x402/fetch'; import { ExactEvmScheme } from '@x402/evm/exact/client'; import { privateKeyToAccount } from 'viem/accounts'; const signer = privateKeyToAccount(process.env.BUYER_PRIVATE_KEY); const fetchWithPayment = wrapFetchWithPaymentFromConfig(globalThis.fetch, { schemes: [{ network: 'eip155:84532', client: new ExactEvmScheme(signer) }], }); const res = await fetchWithPayment('https://<host>/alice/weather/v1/now?city=NYC'); const data = await res.json(); console.log(data); // upstream response console.log(res.headers.get('PAYMENT-RESPONSE')); // settlement info
for providers

Register an API

Register any HTTP endpoint as a paid, metered API. No code changes to your upstream required.

Prerequisites

  • A Base wallet (MetaMask, Coinbase Wallet, Rainbow) or email OTP account
  • ~0.005 SOL for transaction fees and vault rent
  • A publicly reachable HTTP endpoint (or tunneled via ngrok, cloudflare tunnel, etc.)

Via the dashboard

01
sign in to the dashboard

Connect your wallet or use email OTP. Registering your first API creates your vault on-chain automatically.

02
click "Register API"

Enter a name (used in your proxy URL) and your upstream base URL. The name forms a permanent part of your proxy address — choose carefully.

03
set a price per request

Enter a USDC amount. Set 0 for a free but metered API — useful for analytics or gating before a paid launch.

04
copy your proxy URL

Your endpoint is live at <your-host>/{username}/{api-name}. All sub-paths forward verbatim: /alice/weather/v1/nowupstream.url/v1/now.

Via the SDK roadmap

Not yet shipped. The GlobalAPI SDK is on the v0.2 roadmap. Until then, register APIs through the dashboard or hit the HTTP endpoints directly (see API Reference → Endpoints). The snippet below previews the planned shape.
javascript (planned)
const api = await client.register({ name: 'my-api', // → <host>/you/my-api upstream: 'https://…', pricePerRequest: 0.01, // USDC. 0 = free+metered description: 'What your API does', }); // update price anytime — takes effect immediately await client.api('my-api').setPrice(0.005); // pause / resume await client.api('my-api').disable(); await client.api('my-api').enable();
API names are permanent. The name in your proxy URL cannot be changed after registration. All on-chain state is seeded from it.
for providers

Pricing & Fees

You set the price. GlobalAPI takes a small platform fee at collection time. Everything else goes directly to your wallet.

Platform fee structure

parametervaluenote
platform_fee_bps1000 bps (10%)Currently 1000 bps; lives in the on-chain global config and is adjustable via setFeeBps(). Deducted at collect time, not per-request.
minimum_price0 USDCFree APIs are supported — pure metering with no fee taken
fee_destinationGlobalAPI platform vaultSplit happens atomically in withdraw() on-chain
payout_latency~2sBase finality. Collect whenever you want.
Example: You charge $0.01/request. 1,000 calls = $10.00 in your vault. On collect: you receive $9.00 USDC, GlobalAPI receives $1.00.

Changing your price

Price changes are instant — the next request is billed at the new rate. There is no migration, no notice period required.

javascript
await client.api('weather').setPrice(0.001); // $0.001/req, effective immediately
for providers

Collecting Revenue

Your earnings accumulate in your Base vault. Sweep to your wallet at any time.

From the dashboard

Open the dashboard and find the earnings card. It shows your live vault balance; click claim to invoke withdraw() on-chain. The wallet you're signed in with signs the transaction; the platform fee (currently 10%) goes to GlobalAPI's vault and the remainder lands in your wallet's USDC associated token account — atomically, in one transaction.

From code

The dashboard's claim button is a thin wrapper around one contract call. For headless use, call withdraw() on the factory from any Base RPC — it deploys your vault if needed, sends the platform fee to the fee recipient and the remainder to you, in a single transaction. The reference implementation is at ui/lib/globalapi-contract.ts.

Planned SDK ergonomics roadmap

javascript (planned)
// check your vault balance const { usdc } = await client.balance(); console.log(usdc); // → 142.50 // sweep to your wallet (net of 10% platform fee) const tx = await client.collect(); console.log(tx.hash); // base tx hash console.log(tx.received); // → 128.25 USDC sent to your wallet

No minimum balance is required — collect after one request or a thousand.

for callers

Buyer Guide

Calling an GlobalAPI-proxied API is nearly identical to calling the upstream directly — point your client at the proxy URL and let an x402 helper sign each request from your Base wallet.

URL pattern

pattern
https://<your-host>/{username}/{api-name}/{path}

Everything after the API name is forwarded verbatim — query params, headers, body, and HTTP method all pass through unchanged.

With curl (no payment)

A bare curl hits the proxy but returns 402 Payment Required with a JSON price tag in the body. The buyer must satisfy x402 to receive the upstream response:

shell
$ curl -i https://<host>/alice/weather/v1/now # HTTP/1.1 402 Payment Required # body: { "scheme": "exact", "network": "eip155:84532", "payTo": "<vault>", "amount": 5000 }

With an x402 client

Use an EVM-aware x402 client (e.g. @x402/fetch + @x402/evm) to sign payment payloads automatically. The full working example lives at demo/call.mjs.

javascript (node)
const fetchWithPayment = wrapFetchWithPaymentFromConfig(fetch, { schemes: [{ network: 'eip155:84532', client: new ExactEvmScheme(signer) }], }); const res = await fetchWithPayment('https://<host>/alice/weather/v1/forecast', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ city: 'NYC', days: 7 }), }); const data = await res.json(); console.log(res.headers.get('PAYMENT-RESPONSE')); // settlement signature + amount

Agent & script usage roadmap

Today, agents sign each x402 payment with an EVM private key — no wallet pop-up, no per-call human interaction (see demo/call.mjs). A session-level spend authorization is on the roadmap so an agent can declare an upper bound up front and avoid signing each payload individually:

javascript (planned)
// authorize a spend limit for this session (planned) await client.authorize({ maxSpend: 10.00, expiresIn: '1h' }); // subsequent calls draw from the authorization automatically const r1 = await client.call('alice/weather', { path: '/v1/now' }); const r2 = await client.call('bob/geocode', { path: '/v1/ip' });
for callers

Wallet & USDC Setup

GlobalAPI settles in USDC on Base. Here's how to get set up if you're new to the ecosystem.

Option A — Self-custody (recommended)

01
install a Base wallet

MetaMask (metamask.io) and Coinbase Wallet (coinbase.com/wallet) are wired into the dashboard today. Any wallet that exposes the Base wallet-adapter standard should work; support for more wallets is on the roadmap.

02
get USDC on Base

Buy SOL on Coinbase, Kraken, or Binance, then swap to USDC via Jupiter (jup.ag). Alternatively, bridge USDC from Ethereum using Wormhole or Circle's CCTP.

03
connect to GlobalAPI

Open the dashboard, click sign in, choose your wallet, and approve the connection. The first time you register an API, a small on-chain transaction initializes your user account (vault + USDC ATA) — a one-time setup cost.

Option B — Email OTP

Sign in with an email address — no wallet required. GlobalAPI creates a wallet for you. Transfer USDC from an external wallet to fund it.

Note: Email OTP accounts are custodial in v0.1. For production use or large balances, connect your own wallet for full self-custody.
sdk

Installation roadmap

The GlobalAPI SDK is in design — JavaScript / TypeScript, Python, Rust, and Go are planned for v0.2 on a single release cadence. None of the package commands below resolve yet. They preview the planned ergonomics.

Until the SDK ships: Use the dashboard to register and manage APIs. For programmatic access, hit the HTTP endpoints directly (see Endpoints) and use any x402-compatible EVM client (e.g. @x402/fetch — see demo/call.mjs) for buyer-side calls.
terminal
$ npm install @globalapi-sh/sdk # or $ bun add @globalapi-sh/sdk $ pnpm add @globalapi-sh/sdk

Requires Node 18+ or Bun 1+. Full TypeScript types included.

terminal
$ pip install globalapi-sdk # or $ poetry add globalapi-sdk $ uv add globalapi-sdk

Requires Python 3.10+. Async-first via asyncio; sync wrappers available.

Cargo.toml
[dependencies] globalapi-sdk = "0.1" tokio = { version = "1", features = ["full"] }

Async-native with Tokio. MSRV: Rust 1.75.

terminal
$ go get github.com/globalapi-sh/sdk-go@latest

Requires Go 1.22+. Context-aware; all calls accept context.Context.

sdk

Provider SDK roadmap

For API providers — registering endpoints, managing pricing, and collecting revenue. Planned shape; not yet released.

javascript
import { GlobalAPI } from '@globalapi-sh/sdk'; const client = new GlobalAPI({ privateKey: process.env.GLOBALAPI_PRIVATE_KEY }); // register const api = await client.register({ name: 'my-api', upstream: 'https://…', pricePerRequest: 0.01 }); // list all your APIs const apis = await client.apis(); // update price await client.api('my-api').setPrice(0.005); // disable / enable await client.api('my-api').disable(); // check balance const { usdc } = await client.balance(); // collect to your wallet const tx = await client.collect();
python
from globalapi import GlobalAPI import os client = GlobalAPI(private_key=os.environ["GLOBALAPI_PRIVATE_KEY"]) # register api = await client.register(name="my-api", upstream="https://…", price_per_request=0.01) # update price await client.api("my-api").set_price(0.005) # collect balance = await client.balance() # → { 'usdc': 142.5 } tx = await client.collect()
rust
use globalapi_sdk::{GlobalAPI, RegisterOptions}; let client = GlobalAPI::new(&private_key); // register let api = client.register(RegisterOptions { name: "my-api".into(), upstream: "https://…".into(), price_per_request: 0.01, ..Default::default() }).await?; // collect let balance = client.balance().await?; let tx = client.collect().await?;
go
import ( globalapi "github.com/globalapi-sh/sdk-go" "os" ) client := globalapi.New(os.Getenv("GLOBALAPI_PRIVATE_KEY")) // register api, err := client.Register(globalapi.RegisterOptions{ Name: "my-api", Upstream: "https://…", PricePerRequest: 0.01, }) // collect tx, err := client.Collect(ctx)
sdk

Caller SDK roadmap

For API consumers — calling paid endpoints with automatic payment handling. Planned shape; today, use an x402 client directly (see demo/call.mjs).

javascript
const client = new GlobalAPI({ apiKey: process.env.GLOBALAPI_API_KEY }); // call a paid API const res = await client.call('alice/weather', { path: '/v1/now', params: { city: 'NYC' }, }); // pre-authorize a session spend limit (agent-friendly) await client.authorize({ maxSpend: 5.00, expiresIn: '1h' }); // check usage const usage = await client.usage({ since: '24h' }); // → { calls: 842, spent: { usdc: 4.21 } }
python
client = GlobalAPI(api_key=os.environ["GLOBALAPI_API_KEY"]) # call a paid API res = await client.call("alice/weather", path="/v1/now", params={"city": "NYC"}) print(res.data) # → {'temp': 72, 'unit': 'F'} # authorize a spend cap await client.authorize(max_spend=5.00, expires_in="1h") # usage stats usage = await client.usage(since="24h")
rust
let client = GlobalAPI::with_api_key(&api_key); let res = client.call("alice/weather", CallOptions { path: "/v1/now".into(), params: hashmap!{ "city" => "NYC" }, ..Default::default() }).await?; let usage = client.usage(UsageOptions { since: Since::Hours(24) }).await?;
go
client := globalapi.WithAPIKey(os.Getenv("GLOBALAPI_API_KEY")) res, err := client.Call(ctx, "alice/weather", globalapi.CallOptions{ Path: "/v1/now", Params: map[string]string{"city": "NYC"}, }) usage, err := client.Usage(ctx, globalapi.UsageOptions{Since: "24h"})
sdk

Configuration roadmap

All SDK clients will share a common configuration interface. Preview only — these options are part of the v0.2 SDK design.

optiontypedescription
privateKeystringEVM private key (0x-prefixed hex). Required for provider operations. Never expose in client-side code.
apiKeystringGlobalAPI API key (enig_live_… or enig_test_…). Required for caller operations.
network'base-sepolia' | 'base'Defaults to 'Base Sepolia'. Switch to 'mainnet' at launch.
timeoutnumber (ms)Request timeout applied to each proxied call. Default: 30000.
retriesnumberRetry count on upstream 5xx errors. Payment is refunded on retry. Default: 1.
rpcUrlstringCustom Base RPC endpoint. Defaults to GlobalAPI's managed RPC.
api reference

Authentication

GlobalAPI has two distinct authentication models — one for callers (paying for proxy requests) and one for providers (managing their APIs).

Caller auth — x402 payment protocol

Proxied requests are gated by the x402 payment protocol, not API keys. The flow:

  1. 1. The first request returns 402 Payment Required with a JSON price tag (network, recipient vault, amount in USDC).
  2. 2. Your client signs a payment payload with your EVM private key and re-sends the request with a PAYMENT header.
  3. 3. The GlobalAPI proxy validates the payment, settles it on Base, then forwards your request upstream. The settlement signature is returned in the PAYMENT-RESPONSE header.

In practice, you don't implement this by hand — use @x402/fetch with the SVM scheme, point it at a signer, and call the proxy URL like a normal fetch. See demo/call.mjs for a working 50-line example.

Provider auth — wallet signature or email OTP

Provider operations (registering APIs, updating prices, collecting revenue) authenticate via the dashboard:

methodhow it works
Base walletMetaMask or Coinbase Wallet — connect, sign the transaction, your wallet pubkey is your provider identity.
Email OTPSign in with email; the backend issues a wallet custodied during v0.1. Convert to a self-custodial wallet anytime.

Future API-key auth roadmap

A first-party API key system (for headless dashboards, CI, scripts that prefer key-based auth over wallet signatures) is on the roadmap. The planned prefix scheme:

prefixenvironmentfunds
enig_live_MainnetReal USDC
enig_test_Base SepoliaTest tokens — no real value
api reference

Endpoints

Base URL: your GlobalAPI deployment host (Base Sepolia: api.globalapi.live). The routes below are the surface area today — flat, no /v1 prefix.

Proxy (x402-priced)

ANY
/{user_name}/{api_name}/*path
Forwards to the API's upstream URL. The request must satisfy the x402 price tag; the proxy settles payment on Base before forwarding. All HTTP methods pass through verbatim.
POST
/{user_name}/{api_name}
Same as above for POST to the root of the API (no sub-path).

Discovery

GET
/browse
List all public APIs in the marketplace.
GET
/{user_name}
Public user profile.
GET
/{user_name}/apis
List APIs owned by a user.
GET
/{user_name}/{api_name}
API metadata (name, description, upstream — sanitized — price, category).
GET
/user/pubkey/{pubkey}
Look up a user by their Base public key.

Provider management

POST
/create_user
Create a user record. Body includes user_name and the Base public key tied to the account.
POST
/{user_name}/create_api
Register a new API. Body: { name, upstream, price_per_request, description?, category? }
DELETE
/{user_name}/{api_name}
Delete an API.
Note — price updates and vault balance collection happen on-chain today (via the setFeeBps() / withdraw() instructions). There is no separate HTTP endpoint for them; the dashboard wraps the on-chain calls. Headless wrappers are part of the SDK roadmap.

Email OTP

POST
/send_otp
Send a one-time code to an email address. Body: { email }
POST
/verify_otp
Verify the code. Body: { email, otp }

Planned roadmap

GET
/v1/usage
Usage and spend stats for a caller — planned alongside the SDK.
POST
/v1/authorize
Session-level spend authorization for agents.
security

Trust Model

GlobalAPI is built on one principle: the platform should never be able to steal from its users.

How funds flow

When a caller pays for a request, USDC moves from their account directly into a vault address derived from the developer's wallet address. At no point does USDC pass through GlobalAPI's own wallet.

entitycan drain developer vault?
GlobalAPI platformno — no admin key exists
Other developersno — vault seeded by your key only
API callersno — can only pay in, never withdraw
You (the developer)yes — only you can invoke withdraw()
If GlobalAPI goes offline: Your vault and its USDC balance remain on-chain. You can invoke withdraw() directly via any Base RPC — no GlobalAPI infrastructure needed. The program is immutable once deployed.
security

Non-Custodial Design

Every dollar you earn sits in a vault whose address is derived from your wallet address. The math that generates this address ensures only you can authorize a withdrawal.

vault seed derivation

rust (on-chain)
// programs/globalapi/src/instructions/withdraw().rs #[account( seeds = [b"USER_DATA_SEEDS", global_config.key().as_ref(), developer.key().as_ref()], // your wallet pubkey bump = user_data.bump, constraint = user_data.dev == developer.key() )] pub user_data: Account<UserData>, // Only a signer derivable from these exact seeds can // sign the transfer_checked CPI out of this account. transfer_checked( CpiContext::new_with_signer( token_program, TransferChecked { from: user_data_ata, to: dev_ata, authority: user_data.to_account_info() }, signer_seeds), net, mint.decimals)?;

Verify your vault on-chain

Inspect your vault and its USDC balance at any time using any Base RPC or explorer:

shell
$ base account YOUR_PDA_ADDRESS --url Base Sepolia $ spl-token balance --address YOUR_PDA_ATA --url Base Sepolia

The factory address is see contracts/deployments/base-sepolia.json (Base Sepolia). Source code is publicly auditable on GitHub.

faq

FAQ

Do I need to change my API code to use GlobalAPI? +
No. GlobalAPI is a proxy layer. Your upstream API receives requests exactly as before — it never knows GlobalAPI is in the middle. No new dependencies, no middleware, no code changes.
What happens if my upstream API goes down? +
If the proxy receives a 5xx response from your upstream, the caller is automatically refunded. The USDC transfer is reverted before it settles. GlobalAPI does not charge for failed requests.
Can I offer a free tier alongside a paid tier? +
Yes. Set pricePerRequest: 0 for free-but-metered access. Register a separate API name for the paid version, or use the upcoming tiered pricing feature (Q3 roadmap) for rate-limited free + paid overages on one endpoint.
How fast do I receive payment? +
Payment settles inside the request cycle on Base — typically a couple of seconds. Your vault balance updates before the caller receives the response. Collect to your wallet anytime after that.
Can AI agents call GlobalAPI-proxied APIs? +
Yes — this is one of our primary use cases. Today, agents sign each x402 payment directly from a EVM private key (no wallet pop-up, no human in the loop — see demo/call.mjs). A session-level spend-cap helper (client.authorize()) is on the roadmap so agents can declare an upper bound once and avoid per-call signing.
Is the platform fee negotiable? +
The current platform fee is 10% (1000 bps), set in the on-chain global config. For high-volume design partners, we're open to custom rates — reach out on Discord or directly after the pitch.
What blockchains are supported? +
Base only, currently. Settlement is in USDC (SPL token). An Ethereum / x402 protocol bridge is on the 90-day roadmap for cross-chain access.
Is GlobalAPI open source? +
Yes. The Anchor program, the Rust proxy server, and the Next.js dashboard all live in the same monorepo and are verifiably deployed on-chain (factory address below). The SDK will join the same repo when it's ready.
What happens to my funds if GlobalAPI shuts down? +
Nothing bad. Your vault and its USDC balance live on-chain permanently. You can call withdraw() directly via any Base RPC — no GlobalAPI servers required. The program is immutable once deployed, and your funds are always recoverable.