Skip to main content
Onboarding a user in the European Economic Area (EEA) uses the same capability-driven model as any other user — you just have a couple of extra requirements to satisfy, because EEA ramps run under the EU’s Markets in Crypto-Assets regulation (MiCA). You never hard-code these steps. You read the user’s capabilities, satisfy whatever requirements are outstanding, and re-read until the ramp is active. This guide walks the full EEA path for a SEPA off-ramp; the shape is identical for on-ramps.
New to the capability model? Read Onboarding customers first — this guide assumes you’ve created the user and started identity verification.

The extra requirements

For an EEA user, a ramp capability (e.g. crypto_to_fiat / sepa_credit_transfer) can surface up to three requirements. Each tells you how to satisfy it: terms_acceptance and regional_compliance are the two that need you to submit something back — the rest of the model is the familiar “visit actionUrl, then re-fetch capabilities”.

The flow

1

Create and verify the user

Create the user and start identity verification exactly as in Onboarding customers. Verification produces the identity data the EEA path needs, so it comes first.
2

Read capabilities

GET /v1/users/me. The SEPA capability comes back requirements_needed with its outstanding requirements and a nextRequirement.
3

Accept the terms

Send the user to the terms_acceptance requirement’s actionUrl (a hosted terms page). When they accept, the flow returns a signed agreement id. Submit it:
The agreementId is opaque — you just relay what the hosted flow gave you. Accepting the terms is what provisions the user’s EEA account behind the scenes.
4

Submit MiCA compliance fields

Check what’s outstanding, collect the fields, and submit them together:
See Regional compliance for the full field reference (ISO alpha-3 codes, the account-purpose list, and validation).
5

Finish identity verification (if asked)

Identity is normally satisfied by the verification from step 1. If the provider’s own checks need more — for example an address that didn’t match a registry — the identity_verification requirement stays with an actionUrl. Send the user there to complete it.
6

Re-read capabilities and transact

You don’t need to poll for this. Subscribe to the capabilities.updated webhook and re-fetch GET /v1/users/me when it fires — you’ll be notified as each requirement is processed and cleared. Once every requirement clears, the SEPA capability flips to active and money movement unblocks. Until then, transactions are refused with the outstanding requirement.Add the destination bank account and create the off-ramp — see Off-ramp: crypto to bank.
Listen, don’t poll. Provider checks (KYC, the SEPA endorsement, database screens) resolve asynchronously, sometimes minutes apart. Rather than polling GET /v1/users/me on a timer, subscribe to the capabilities.updated webhook — Spritz notifies you whenever a requirement or capability status changes, and you re-fetch only then.
While a ramp capability is requirements_needed, money movement on it is blocked — the requirements are a hard gate, not a soft prompt. Drive your UI off capabilities so the user always sees exactly what’s left.

Endpoint reference

Next

Regional compliance

The MiCA field reference — place of birth, nationalities, account purpose.

Onboarding customers

The capability-driven model these steps build on.

Off-ramp: crypto to bank

Put the active SEPA capability to work.

Webhooks

React to capabilities.updated instead of polling.