Create participant

POST
/providers/{providerID}/participants

Create a participant: your customer who sends money with Moov Money. The externalID is unique within your provider. Creating one that already exists returns 201 with the existing participantID and leaves the stored record unchanged. A participant is scoped to one provider. The same person can be a participant of more than one provider; each provider keeps its own externalID and record.

Creation is asynchronous. The 201 response returns the assigned participantID and echoes the identity fields from the request (externalID, name fields, dateOfBirth, address, phones, emails). Optional fundingSources on the request are persisted but are not returned in the 201 body. Read the canonical record, including status, at GET /providers/{providerID}/participants/{participantID} once creation completes.

Send an X-Idempotency-Key header so a retried create is processed once. The server echoes that header on the response. The key is retained for 24 hours after the create completes. Replaying the same key with the same request body within that window returns the original 201 response. Replaying it with a different body within that window returns a 409 with error code idempotency-key-reused. After the window, the same key starts a new create. Returns a 409 with error code idempotency-request-in-progress when a request with this key is still running. Returns 400 when the header is missing or malformed.

Auth: API key or bearer token. Scoped to the calling provider. Returns 422 when the body fails validation.

Request
cURL
curl -X POST https://api.moov.money/providers/{providerID}/participants \
  -u "$MOOV_API_KEY_ID:$MOOV_API_KEY_SECRET" \
  -H "X-Moov-Version: v2026.10.00" \
  -H "X-Idempotency-Key: $(uuidgen)" \
  -H "Content-Type: application/json" \
  -d '{
  "address": {
    "addressLine1": "123 Main St",
    "addressLine2": "Apt 4B",
    "city": "San Francisco",
    "country": "US",
    "postalCode": "94105",
    "stateOrProvince": "CA"
  },
  "emails": [
    "[email protected]"
  ],
  "externalID": "customer-abc-123",
  "familyName": "Smith",
  "fundingSources": [
    {
      "displayName": "First National Checking",
      "fundingType": "bank_account",
      "last4": "4321",
      "providerSourceID": "src_01HP5J9ZKQT4RXP8M2VYBN3D"
    }
  ],
  "givenName": "Jane",
  "phones": [
    {
      "countryCode": "1",
      "number": "5555550101"
    }
  ]
}'
Responses
201 400 401 409 422
The resource was successfully created.
{
  "address": {
    "addressLine1": "123 Main St",
    "addressLine2": "Apt 4B",
    "city": "San Francisco",
    "country": "US",
    "postalCode": "94105",
    "stateOrProvince": "CA"
  },
  "emails": [
    "[email protected]"
  ],
  "externalID": "customer-abc-123",
  "familyName": "Smith",
  "givenName": "Jane",
  "participantID": "3v2whagmwvbujhwbt7v3nl6ffq_user",
  "phones": [
    {
      "countryCode": "1",
      "number": "5555550101"
    }
  ]
}
Malformed request: the body or headers failed validation.
Response body application/problem+json
RFC 9457 Problem Details error body, served as application/problem+json. From v2026.10.00, every error response that has a body uses this schema.

type

string required
URI that tells you which problem occurred. Branch on this value; it never changes. Moov problem types look like https://api.moov.money/errors#<code> (for example invalid-request, idempotency-key-reused, or idempotency-request-in-progress). Treat the value as an opaque constant and do not fetch it. about:blank means the HTTP status code says everything there is to know.

title

string required
Short human-readable name of the problem type. Fixed per type; defaults to the HTTP status text.

status

integer<int32> required
The HTTP status code of this response.

detail

string
Human-readable explanation of this specific occurrence.

instance

string
URI reference that identifies this specific occurrence.

errors

array<object>
The request-body fields that failed validation. Present on validation errors only.
Show child attributes

errors[]

pointer

string required
RFC 6901 JSON Pointer to the field, using the public JSON field names. If the field is missing, the pointer shows where it belongs.

detail

string required
What is wrong with the field.
Authentication missing, invalid, or insufficient.
The request conflicts with the current state of the target resource.
Response body application/problem+json
RFC 9457 Problem Details error body, served as application/problem+json. From v2026.10.00, every error response that has a body uses this schema.

type

string required
URI that tells you which problem occurred. Branch on this value; it never changes. Moov problem types look like https://api.moov.money/errors#<code> (for example invalid-request, idempotency-key-reused, or idempotency-request-in-progress). Treat the value as an opaque constant and do not fetch it. about:blank means the HTTP status code says everything there is to know.

title

string required
Short human-readable name of the problem type. Fixed per type; defaults to the HTTP status text.

status

integer<int32> required
The HTTP status code of this response.

detail

string
Human-readable explanation of this specific occurrence.

instance

string
URI reference that identifies this specific occurrence.

errors

array<object>
The request-body fields that failed validation. Present on validation errors only.
Show child attributes

errors[]

pointer

string required
RFC 6901 JSON Pointer to the field, using the public JSON field names. If the field is missing, the pointer shows where it belongs.

detail

string required
What is wrong with the field.
The request was well-formed but couldn’t be processed (e.g. card declined).
Response body application/problem+json
RFC 9457 Problem Details error body, served as application/problem+json. From v2026.10.00, every error response that has a body uses this schema.

type

string required
URI that tells you which problem occurred. Branch on this value; it never changes. Moov problem types look like https://api.moov.money/errors#<code> (for example invalid-request, idempotency-key-reused, or idempotency-request-in-progress). Treat the value as an opaque constant and do not fetch it. about:blank means the HTTP status code says everything there is to know.

title

string required
Short human-readable name of the problem type. Fixed per type; defaults to the HTTP status text.

status

integer<int32> required
The HTTP status code of this response.

detail

string
Human-readable explanation of this specific occurrence.

instance

string
URI reference that identifies this specific occurrence.

errors

array<object>
The request-body fields that failed validation. Present on validation errors only.
Show child attributes

errors[]

pointer

string required
RFC 6901 JSON Pointer to the field, using the public JSON field names. If the field is missing, the pointer shows where it belongs.

detail

string required
What is wrong with the field.

Headers

X-Moov-Version

string
Set this header to the API version being targeted (e.g. v2026.10.00). When omitted, the server applies its default version.

X-Idempotency-Key

string required
Client-supplied key that identifies this create request, 1 to 255 characters. Send the header once. Retries with the same key are processed once for 24 hours after the request completes.

Path parameters

providerID

string required
Your provider account ID.

Request

application/json
A participant to create: your customer who will send money with Moov Money. The externalID must be unique within your provider scope. Creating a participant with an externalID that already exists returns 201 with the existing participantID and does not update the record.

externalID

string required
Your identifier for this participant. Must be unique within your provider scope. Use the customer identifier from your core banking system; when your bank has no external customer ID to reuse, your digital banking ID for the customer works well.

givenName

string required
Participant’s given (first) name.

middleName

string
Participant’s middle name or middle initial.

familyName

string required
Participant’s family (last) name.

nickName

string
Name the participant goes by, for example Bob for Robert.

dateOfBirth

string<date>
Participant’s date of birth, YYYY-MM-DD. Used for identity checks, such as flipping an OFAC hit.

address

object required
Participant’s primary postal address. Required, matching what you collect for a recipient; all address fields must be present.
Show child attributes

address

addressLine1

string required
First line of the street address.

addressLine2

string
Second line of the street address (apartment, suite, etc.).

city

string required
City / locality.

stateOrProvince

string required
State, province, or region.

postalCode

string required
Postal / ZIP code.

country

string required
ISO 3166-1 alpha-2 country code.

phones

array<object> required
Phones on the participant. At least one is required.
Show child attributes

phones[]

countryCode

string required
ITU country calling code without a leading plus. ASCII digits only.

number

string required
National significant number without the country calling code. ASCII digits only.

emails

array<string>
Email addresses. May be empty.

fundingSources

array<object>
Optional initial funding sources to persist with the participant. At most 10. Each pair of fundingType and providerSourceID must be unique in the array. Re-sending the same source on a later create converges to the existing record. These values are not returned in the 201 body.
Show child attributes

fundingSources[]

fundingType

string<enum> required
Funding source discriminator.
Possible values: card, bank_account

providerSourceID

string [1 to 256] characters required
Your identifier for the underlying funding source. Must be 1–256 characters.

displayName

string [1 to 256] characters required
Human-readable display label. Must be 1–256 characters.

last4

string
Last four digits of the funding source number: the card number for card, or the bank account number for bank_account. Rendered with displayName in the UI. At most 4 characters.

Response

Response envelope for create participant. Returns the assigned participantID and echoes the accepted request. Read the canonical record at the get-participant endpoint once creation completes.

externalID

string required
Your identifier for this participant. Must be unique within your provider scope. Use the customer identifier from your core banking system; when your bank has no external customer ID to reuse, your digital banking ID for the customer works well.

givenName

string required
Participant’s given (first) name.

middleName

string
Participant’s middle name or middle initial.

familyName

string required
Participant’s family (last) name.

nickName

string
Name the participant goes by, for example Bob for Robert.

dateOfBirth

string<date>
Participant’s date of birth, YYYY-MM-DD. Used for identity checks, such as flipping an OFAC hit.

address

object required
Participant’s primary postal address. Required, matching what you collect for a recipient; all address fields must be present.
Show child attributes

address

addressLine1

string required
First line of the street address.

addressLine2

string
Second line of the street address (apartment, suite, etc.).

city

string required
City / locality.

stateOrProvince

string required
State, province, or region.

postalCode

string required
Postal / ZIP code.

country

string required
ISO 3166-1 alpha-2 country code.

phones

array<object> required
Phones on the participant. At least one is required.
Show child attributes

phones[]

countryCode

string required
ITU country calling code without a leading plus. ASCII digits only.

number

string required
National significant number without the country calling code. ASCII digits only.

emails

array<string>
Email addresses. May be empty.

participantID

string required
Unique identifier for this participant, assigned before creation completes.