Getting started
Build a sandbox-to-production PIX-to-USDT integration in five minutes.
Build a PIX-to-USDT integration
Accept BRL via Pix from your end users; settle USDT to a wallet you control. This guide takes you from "I just got an API key" to "I made a real authenticated call" in about five minutes.
What you'll do
Get your sandbox key
Receive your `sk_test_…` key by email. Sandbox is a live mirror of BlendFi where no real money moves.
Authenticate every request
Every `/v1/*` call carries your key as a Bearer token. No login, no session — the key is the session.
Create your first user
Pass an `external_id`, name, and CPF. Get back a BlendFi user ID you'll reference for every transaction.
Quickstart
1. Set your environment
Drop your sandbox key into a shell variable so the rest of the examples are copy-paste friendly.
export BLENDFI_KEY=sk_test_replace_with_your_real_key
export BLENDFI_BASE=https://api.sandbox.blendfi.com.brYou can tell which environment a key targets by its prefix:
| Prefix | Environment | What it can do |
|---|---|---|
sk_test_… | Sandbox | Anything. No real money moves. |
sk_live_… | Production | Real money. Issued only after compliance review. |
A sandbox key cannot accidentally hit production, and a production key cannot hit sandbox — both are rejected with 401 authentication_failed.
2. Authenticate every request
Every call to /v1/* carries your key in the Authorization header as a Bearer token:
Authorization: Bearer sk_test_…Three things to know:
- The word
Beareris required. JustAuthorization: sk_test_…returns401 authentication_required. - The key is sent on every request. There is no login, no session cookie, no token refresh. The key is the session.
- Capabilities are per-key. A key has a list of capabilities (e.g.
users:create,transactions:create). If a key tries an endpoint it isn't scoped for, you get403 missing_capability. Most partners start with a sandbox key scoped for everything; production keys are tighter.
3. Make your first call
Create a test user. This is the canonical "first call" because most other endpoints need a user ID.
curl -X POST $BLENDFI_BASE/v1/users \
-H "Authorization: Bearer $BLENDFI_KEY" \
-H "Idempotency-Key: $(uuidgen)" \
-H "content-type: application/json" \
-d '{
"external_id": "your-internal-user-id-001",
"name": "Ada Lovelace",
"cpf": "52998224725"
}'If everything's wired up:
{
"id": "01J…",
"external_id": "your-internal-user-id-001",
"name": "Ada Lovelace",
"kyc_status": "not_started",
"created_at": "2026-04-29T13:00:00Z"
}That's it. You're authenticated.
CPF format
Use 11 digits, no dots or dashes. The example above (52998224725) is a valid test CPF you can reuse in sandbox. Real CPFs in sandbox get encrypted just like in production — never paste real personal data into the docs.
What Idempotency-Key does
Short version: it's a unique string (we recommend a UUID) that makes the request safe to retry. If your network drops mid-call and you retry with the same key, you get the same response back instead of a duplicate user. Every POST and PATCH in BlendFi requires it — see the dedicated Idempotency guide for the contract details.
Sandbox vs production
Build in sandbox first
Sandbox is a live copy of BlendFi where the same endpoints, response shapes, and error codes apply — but PIX payments are simulated and USDT transfers stay in a test wallet. Build your integration here first; we'll review it before issuing a sk_live_… key.
When you're ready, ask us for a production key. We'll review your sandbox integration end-to-end (idempotency handling, error retries, webhook signature verification) before issuing it.
When something goes wrong
Every error response looks the same:
{
"code": "authentication_required",
"message": "Authorization header missing.",
"request_id": "01KPR9F6MM8G147177J7ZQPJHG"
}| Field | What to do with it |
|---|---|
code | Stable, machine-readable. Branch your code off this. |
message | Human-readable. Don't pattern-match on it; we may rewrite it. |
request_id | Paste this when you ask us for help. Pinpoints your request in our logs. |
The two errors you'll see most often while getting started:
| Code | Why | Fix |
|---|---|---|
401 authentication_required | Authorization header missing or doesn't start with Bearer | Add the header; mind the space after Bearer |
401 authentication_failed | Key is unknown, revoked, or pasted with a typo | Re-copy the key from your onboarding email |
403 missing_capability | Key is valid but not scoped for this endpoint | Email us; we'll widen the key's capabilities |
The full error catalogue lives in the Errors guide.
What to read next
You're authenticated. From here:
Idempotency
Retry-safe POSTs and PATCHes. Read before your second mutating call.
Errors and retries
Every `code` mapped to plain meaning, who caused it, whether to retry, and how.
Transaction lifecycle
Quote → execute → settle. The core money-movement flow, with state diagrams.
KYC flow
Verify a user's identity with Sumsub before they can transact.
API reference
Every endpoint, every parameter, every response shape — auto-generated from the live spec.
Environments and limits
Sandbox vs prod base URLs, current rate limits, how to request raises.
FAQ
Where do I get a sandbox key? Email us. We'll send one within a business day with a default capability set you can refine later.
Can I have more than one key? Yes. We can issue capability-scoped keys (e.g. read-only, or transactions-only) so you can compartmentalize integrations. Ask when you onboard.
How do I rotate a key? Email us; we issue a new key and revoke the old one when you've migrated. There is no self-serve rotation in v1.
Why don't I have a sk_live_… key yet?
Production keys are issued after we've reviewed your sandbox integration and your compliance documentation. Build in sandbox first; we'll tell you when you're ready.
Where do I file a bug?
Email us with the request_id from the response. We can find your request in seconds with that.
