Ramps Overview
Ramps move value between fiat rails and crypto balances. The platform supports two execution modes and exposes price queries to estimate conversions before committing.
Prerequisites
Before creating a ramp for an end-user, the user must be onboarded on the platform. Onboarding handles KYC, identity verification, PEP/FEP declarations, and assigns operational limits — without it, ramp operations will be rejected with USER_NOT_VALIDATED or blocked by limits.
See the User Onboarding section for the full flow, country-specific requirements, and webhook integration. Start with Onboard a new user.
If your platform handles end-user onboarding itself (regulated fintechs, licensed exchanges with mature KYC), see Onboarding models to determine whether the Principal Accounts model applies — in that model, end-users are not onboarded in Manteca and identity travels inline in sender per request.
Automatic vs Manual Mode
| Automatic (Synthetics) | Manual | |
|---|---|---|
| What it is | Platform orchestrates the full stage sequence | You control each deposit/withdraw call explicitly |
| When to use | End-to-end Ramp-on / Ramp-off with no custom routing | Custom flows, split operations, or staged execution |
| Complexity | Low — single API call to create | Higher — you own sequencing logic |
| Control level | Low | Full |
| Status tracking | SYNTHETIC_STATUS_UPDATE webhook | DEPOSIT_DETECTED + WITHDRAW_STATUS_UPDATE webhooks |
In automatic mode, you create a synthetic with a single API call. Once the trigger event occurs (typically the deposit being detected), the platform automatically executes all remaining stages in sequence — no additional API calls are needed.
In manual mode, you listen to webhooks (DEPOSIT_DETECTED, ORDER_STATUS_UPDATE, WITHDRAW_STATUS_UPDATE) and react to each event by calling the next step yourself. You can optionally lock a price and execute a currency exchange order before or after the deposit/withdraw steps. Use GET /v2/prices, POST /v2/price-locks, and POST /v2/orders for this. See Pricing and Orders for details.
What Is a Synthetic?
A synthetic is an orchestration entity that chains multiple stages (deposit → order → withdraw) into a single tracked operation. You create it with one API call; once the trigger event occurs (typically the deposit being detected), the platform automatically executes all remaining stages in sequence — no additional API calls are needed. Progress is reported via the SYNTHETIC_STATUS_UPDATE webhook.
What Happens During a Ramp
Ramp-on (fiat → crypto)
User deposits fiat to assigned address
│
▼
DEPOSIT stage — platform detects inbound fiat (trigger)
│ ← remaining stages execute automatically
▼
ORDER stage — platform buys crypto for fiat
│
▼
WITHDRAW stage — platform sends crypto to configured wallet address
│
▼
SYNTHETIC_STATUS_UPDATE webhook fired (COMPLETED)
Ramp-off (crypto → fiat)
User deposits crypto to assigned address
│
▼
DEPOSIT stage — platform detects inbound crypto (trigger)
│ ← remaining stages execute automatically
▼
ORDER stage — platform sells crypto for fiat
│
▼
WITHDRAW stage — platform sends fiat to configured bank account
│
▼
SYNTHETIC_STATUS_UPDATE webhook fired (COMPLETED)
Each stage transitions the synthetic through STARTING → ACTIVE → WAITING → COMPLETED. See Operation Lifecycle Statuses for the full state machine.
The internal deposit step in a ramp synthetic can be optional depending on your company configuration (as we also provide operational overdrafts). Consult your account manager for details.
Optional execution flags
Ramp synthetics accept two optional flags:
| Field | Effect |
|---|---|
disallowDebt | If true, the operation avoids using operational overdraft in case it's already configured. |
skipDeposit | If true, skips the internal deposit trigger step in order to use user's account balance |
In most integrations, you don't need to send these flags — the defaults work correctly. disallowDebt defaults to false, meaning the system uses company-managed funds if configured. skipDeposit is auto-determined based on your company configuration and the disallowDebt value.
Synthetic creation is idempotent on externalId: if you send the same externalId twice, the second call returns the existing synthetic instead of creating a duplicate. Use unique externalId values per operation and leverage this for safe retries.
Endpoint Reference
| Action | Method | Endpoint |
|---|---|---|
| Get all prices | GET | /v2/prices/direct |
| Get pair price | GET | /v2/prices/direct/{ticker} |
| Create Ramp-on synthetic | POST | /v2/synthetics/ramp-on |
| Create Ramp-off synthetic | POST | /v2/synthetics/ramp-off |
| Get synthetic by ID | GET | /v2/synthetics/{syntheticAnyId} |
Related Pages
- Coverage — supported countries, rails, assets, and execution timings
- Operation Lifecycle Statuses — synthetic, withdraw, and deposit status reference
- Operational Limits — per-identity operation limits and compliance thresholds
- Ramps Error Handling — error codes and handling strategy