Skip to main content

Documentation Index

Fetch the complete documentation index at: https://yanhgming.mintlify.app/llms.txt

Use this file to discover all available pages before exploring further.

Every request to the Marlin API must include an API key. The key identifies your merchant account and determines which environment — live or test — your request targets. This page explains how to create keys, how to pass them, and what to expect when authentication fails.

Create an API key

API keys are managed in Settings → API Keys on the Marlin dashboard. Click Create key, give it a name that describes where you’ll use it (for example, production-server or ci-tests), and copy the value immediately. For security reasons the full key is only shown once. You can create multiple keys and revoke any of them without affecting the others — useful for rotating credentials or isolating access across services.

Pass the key in requests

Include the key in the Authorization header of every API request:
Authorization: Bearer sk_live_...

Using the SDK

The SDK handles the header for you. Pass your key when you instantiate the client:
import { Marlin } from "@marlin/sdk";

const marlin = new Marlin({ apiKey: process.env.MARLIN_API_KEY });
Reading the key from an environment variable keeps it out of your source code. Set MARLIN_API_KEY in your deployment environment or a .env file (and add .env to .gitignore).

Using curl

curl https://api.marlin.dev/invoices \
  -H "Authorization: Bearer sk_live_..." \
  -H "Content-Type: application/json"

Key prefixes

Every Marlin API key starts with a prefix that tells you which environment it targets:
PrefixEnvironmentDescription
sk_live_ProductionProcesses real on-chain payments. Use in your production servers only.
sk_test_Test modeSafe for development and CI. No real funds move.
Use sk_test_ keys during development so you can create invoices, fire webhooks, and run through checkout flows without touching real funds.
Never use a sk_live_ key in client-side code, browser bundles, or mobile apps. Anyone who can read the key can make authenticated API requests on your behalf. Keep secret keys on the server.

Authentication errors

If your key is missing, malformed, or revoked, the API returns a 401 response:
{
  "error": "UNAUTHORIZED",
  "message": "Invalid or missing API key.",
  "code": "unauthorized"
}
Common causes:
  • The Authorization header is absent
  • The key was revoked in Settings
  • You’re using a sk_test_ key against the production API (or vice versa)

Rate limits

The Marlin API enforces rate limits to keep the service stable. Every response includes three headers that tell you where you stand:
HeaderTypeDescription
X-RateLimit-LimitnumberMaximum requests allowed in the current window
X-RateLimit-RemainingnumberRequests remaining in the current window
X-RateLimit-ResetnumberUnix timestamp (seconds) when the window resets
The SDK surfaces the most recent values on the client instance:
const invoice = await marlin.invoices.create({ /* ... */ });

console.log(marlin.lastRateLimit);
// { limit: 100, remaining: 99, reset: 1746000000 }
When you exceed the limit the API returns a 429 Too Many Requests response. The SDK automatically retries requests that fail with 500, 502, 503, or 504 status codes (up to two retries with exponential backoff), but does not retry 429 — you should implement backoff based on the X-RateLimit-Reset value.
For high-throughput workloads, process invoices and customer operations in separate SDK instances or queue your requests to stay within the rate limit window.