> ## Documentation Index
> Fetch the complete documentation index at: https://docs.etherfuse.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Create customer organization

> Creates a customer organization under yours. It starts unapproved; it is approved once its KYC or KYB is. Register its bank accounts and wallets afterwards with [Register payment account](/v2/api-reference/payment-accounts/register-payment-account).

All fields are optional, so `{}` creates a bare personal organization. If `id` is already in use the request returns `409` `conflict`.

## Account types

- `personal`: an individual who completes KYC. Send `userInfo` so we can email them about their verification.
- `business`: a company that completes KYB. `userInfo` is rejected. Send `country` to set up KYB at creation, and add the people who complete it with [Add organization member](/v2/api-reference/members/add-organization-member).

`accountType` defaults to `personal` today and will become required. Send it explicitly.

## Signing customers in

For a **personal** organization whose customer signs in with a JWT (see [JWT User Authentication](/v2/guides/jwt-authentication)), send the JWT `sub` as `id`. A **business** organization has its own id; never reuse a customer's `sub` as one, which returns `409`.



## OpenAPI

````yaml openapi-v2.json POST /organization
openapi: 3.1.0
info:
  title: Etherfuse FX API
  description: >-
    Partner-facing ramp API, version 2: payment accounts, quotes, orders and
    webhooks.
  license:
    name: Proprietary
  version: 2.0.0
servers:
  - url: https://api.sand.etherfuse.com
    description: Sandbox
security:
  - ApiKeyAuth: []
tags:
  - name: Payment Accounts
    description: >-
      Register the bank accounts and wallets that money moves from and to, and
      read their readiness per rail.
  - name: Quotes
    description: Price a transfer between two registered payment accounts.
  - name: Orders
    description: Create orders from quotes and track them.
  - name: Webhook Subscriptions
    description: Subscribe to webhook events.
  - name: Webhook Events
    description: Payloads Etherfuse sends to your webhook subscriptions.
  - name: Sandbox
    description: Endpoints that work only in sandbox, for testing.
  - name: Assets
    description: The markets and tokens a quote can use, and the balances of a wallet.
  - name: Authentication
    description: >-
      Partner JWT authentication: exchange a JWT for an access token, or launch
      a user into the app.
  - name: KYC
    description: >-
      Submit a customer's verification data, documents and questionnaire
      answers, import a verification they already passed elsewhere, and check
      where their KYC stands.
  - name: KYB
    description: Check where a business organization's KYB stands.
  - name: Lookup
    description: >-
      Public reference data: exchange rates, stablebonds, bond costs, country
      codes.
  - name: Organizations
    description: >-
      Your organization, your default partner fee, and the customer
      organizations you create.
  - name: Members
    description: >-
      The people who belong to a customer business organization and complete its
      KYB.
  - name: Statements
    description: >-
      Monthly revenue share statements for closed months, as a list or as a CSV
      or PDF download.
paths:
  /organization:
    post:
      tags:
        - Organizations
      summary: Create customer organization
      description: >-
        Creates a customer organization under yours. It starts unapproved; it is
        approved once its KYC or KYB is. Register its bank accounts and wallets
        afterwards with [Register payment
        account](/v2/api-reference/payment-accounts/register-payment-account).


        All fields are optional, so `{}` creates a bare personal organization.
        If `id` is already in use the request returns `409` `conflict`.


        ## Account types


        - `personal`: an individual who completes KYC. Send `userInfo` so we can
        email them about their verification.

        - `business`: a company that completes KYB. `userInfo` is rejected. Send
        `country` to set up KYB at creation, and add the people who complete it
        with [Add organization
        member](/v2/api-reference/members/add-organization-member).


        `accountType` defaults to `personal` today and will become required.
        Send it explicitly.


        ## Signing customers in


        For a **personal** organization whose customer signs in with a JWT (see
        [JWT User Authentication](/v2/guides/jwt-authentication)), send the JWT
        `sub` as `id`. A **business** organization has its own id; never reuse a
        customer's `sub` as one, which returns `409`.
      operationId: v2CreateOrganization
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/CreateOrganizationRequest'
      responses:
        '201':
          description: The new organization.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Organization'
        '400':
          $ref: '#/components/responses/InvalidRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '409':
          $ref: '#/components/responses/Conflict'
        '500':
          $ref: '#/components/responses/InternalError'
components:
  schemas:
    CreateOrganizationRequest:
      type: object
      properties:
        accountType:
          type:
            - string
            - 'null'
          enum:
            - personal
            - business
          description: >-
            Whether this org is an individual or a company:


            - `personal`: an individual customer completing KYC. Send
            `userInfo`.

            - `business`: a company completing KYB. `userInfo` is rejected.


            Optional today and defaults to `personal`. It will become required,
            so send it explicitly now.
          example: personal
        displayName:
          type:
            - string
            - 'null'
          description: >-
            The organization's display name: the friendly label shown in UIs and
            API responses. For a `business` org completing KYB, the legal entity
            name is captured separately via `legalName`.
        id:
          type:
            - string
            - 'null'
          format: uuid
        userInfo:
          oneOf:
            - type: 'null'
            - $ref: '#/components/schemas/UserInfo'
              description: >-
                Optional info about the end user. Required eventually for
                personal

                orgs. Rejected on business orgs (those don't have a single end
                user).
        country:
          type:
            - string
            - 'null'
          description: >-
            ISO 3166-1 alpha-2 country code (e.g. `MX`). Business orgs only;
            rejected on personal orgs. When provided, Etherfuse generates the
            KYB onboarding at creation, seeding the company entity with this
            country so the user lands straight in KYB. Omit it and the user is
            prompted for their country when they begin KYB.
          example: MX
        legalName:
          type:
            - string
            - 'null'
          description: >-
            Legal entity name for the KYB company entity (e.g. the incorporated
            name on the company's registry documents). Pass it together with
            `country` when generating the KYB onboarding at creation; rejected
            without `country`. Independent of `displayName`: renaming the org
            does not change the legal name, and vice versa.
          example: Acme Corporation S.A. de C.V.
      example:
        accountType: personal
        displayName: Ana Ejemplo
        id: a1b2c3d4-e5f6-7890-abcd-ef1234567890
        userInfo:
          displayName: Ana Ejemplo
          email: ana@example.com
    Organization:
      type: object
      required:
        - id
        - displayName
        - accountType
        - approvedAt
        - createdAt
        - updatedAt
      properties:
        id:
          type: string
          format: uuid
        displayName:
          type: string
        accountType:
          $ref: '#/components/schemas/AccountType'
        approvedAt:
          type:
            - string
            - 'null'
          format: date-time
          description: When the organization's KYC or KYB was approved. Null until then.
        createdAt:
          type: string
          format: date-time
        updatedAt:
          type: string
          format: date-time
      example:
        id: b2c3d4e5-f6a7-8901-bcde-f12345678901
        displayName: Ana Ejemplo
        accountType: personal
        approvedAt: null
        createdAt: '2026-10-01T14:30:00Z'
        updatedAt: '2026-10-01T14:30:00Z'
    UserInfo:
      type: object
      description: >-
        Info about the end user, collected at org/customer creation time. The

        user record is pre-populated with the partner's display name and email
        so

        the customer's eventual Firebase sign-in attaches to the correct user,
        so

        we can send status-change emails, and so the verification record has an

        email address.
      required:
        - email
        - displayName
      properties:
        displayName:
          type: string
        email:
          type: string
    AccountType:
      type: string
      enum:
        - personal
        - business
      description: >-
        `personal`: an individual who completes KYC. `business`: a company that
        completes KYB.
    Problem:
      type: object
      description: >-
        RFC 9457 problem details. Every v2 error uses this body with content
        type `application/problem+json`. `errors` is present only on
        `validation-error`. `required` and `missing` are present only on
        `registration-info-required`.
      required:
        - type
        - title
        - status
        - detail
        - instance
      properties:
        type:
          type: string
          format: uri
          description: >-
            `https://docs.etherfuse.com/ramp/v2/errors/` followed by the problem
            slug, for example
            `https://docs.etherfuse.com/ramp/v2/errors/quote-expired`. Switch on
            this value.
          example: https://docs.etherfuse.com/ramp/v2/errors/quote-expired
        title:
          type: string
          description: Short summary of the problem type.
          example: Quote expired
        status:
          type: integer
          description: The HTTP status code.
          example: 400
        detail:
          type: string
          description: Human-readable explanation of this occurrence. Do not parse it.
          example: >-
            quote 5e6f7a8b-9c0d-4e1f-8a2b-3c4d5e6f7a8b has expired or does not
            exist
        instance:
          type: string
          description: Unique identifier for this occurrence. Quote it to support.
          example: >-
            tag:etherfuse.com,2026-08-28:R2-10120/0b1c2d3e-4f50-4a6b-8c7d-9e0f1a2b3c4d
        errors:
          type: array
          description: Present on `validation-error`. One entry per invalid field.
          items:
            $ref: '#/components/schemas/FieldViolation'
        required:
          type: array
          description: >-
            Present on `registration-info-required`. Every registration field
            the route requires, as JSON Pointers into the request, for example
            `#/registrationInfo/taxId`.
          items:
            type: string
        missing:
          type: array
          description: >-
            Present on `registration-info-required`. The required fields you
            must still send, as JSON Pointers into the request.
          items:
            type: string
    FieldViolation:
      type: object
      required:
        - pointer
        - detail
      properties:
        pointer:
          type: string
          description: >-
            JSON Pointer to the field in the request, for example
            `#/accountDetails/clabe`.
          example: '#/accountDetails/clabe'
        detail:
          type: string
          description: What is wrong with the field.
          example: This field is required.
  responses:
    InvalidRequest:
      description: >-
        `invalid-request`: a path, query or body value is malformed, or
        `pageSize` is 0 or over 100.
      content:
        application/problem+json:
          schema:
            $ref: '#/components/schemas/Problem'
    Unauthorized:
      description: >-
        `unauthorized`: the `Authorization` header is missing, not ASCII, or
        does not hold a valid API key.
      content:
        application/problem+json:
          schema:
            $ref: '#/components/schemas/Problem'
    Conflict:
      description: >-
        `conflict`: the request conflicts with the resource's current state.
        `detail` says how.
      content:
        application/problem+json:
          schema:
            $ref: '#/components/schemas/Problem'
    InternalError:
      description: >-
        `internal-error`: an unexpected error on our side. Retry with backoff,
        and quote `instance` to support if it persists.
      content:
        application/problem+json:
          schema:
            $ref: '#/components/schemas/Problem'
  securitySchemes:
    ApiKeyAuth:
      type: apiKey
      in: header
      name: Authorization
      description: API key sent in the Authorization header, with no `Bearer` prefix.

````

This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.