Elaichi Current user API

The Current user API from Elaichi — 1 operation(s) for current user.

GitHub OpenAPI

Operations 1

GET /user/me Get the current user and their organizations #

Work with this as data

Every API here is available over the APIs.io API and to AI agents over MCP.

MCP server

One button, every client — Claude, Cursor, VS Code and the rest.

https://apis.io/mcp

Tools for apis

7 MCP tools reach this
  • find_apisBrowse and filter every API in the catalog.
  • get_api_artifactsOne API's artifacts, grouped by type.
  • get_openapiThe primary OpenAPI for this API.
  • find_similar_apisAPIs that look like this one.
  • apis_io_searchSTART HERE — APIs, providers and tags for one query, each with its total.
  • resolveTurn a domain, URL or GitHub org into the provider it belongs to.
  • find_cohortsEvery scored population of providers in the catalog.
All 92 tools →

Call it yourself

curl for this page
This API
curl "https://apis.io/api/v1/apis/elaichi-ai:elaichi-ai-current-user-api"
All apis
curl "https://apis.io/api/v1/apis?limit=25"

Calls without X-API-Key need no key. Calls with it need a paid plan — get a key.

Get an API key

Free tier, no form to fill in. Signing in shares your email address with us — we store it to create your key and to recognise you if you sign in with another provider. See our Privacy Policy and Terms.

A second provider on the same verified email joins the account you already have.

OpenAPI Specification

elaichi-ai-current-user-api-openapi.yml Raw ↑
openapi: 3.2.0
info:
  title: Elaichi Current user API
  version: 0.1.0
  description: 'Control-plane HTTP API for Elaichi, the MCP control plane for SaaS teams. Authenticate with an organization API token (create one in the Elaichi app under Settings → API tokens) sent as a bearer token, plus the `X-Organization-Id` header on org-scoped routes; the MCP and OAuth endpoints use their own protocols. A few actions are deliberately not available to an API token and must be done by a person in the Elaichi app: managing API and SCIM tokens, creating an organization, approving an access request, deleting an organization, and changing the two-factor requirement. The operations concerned say so. Endpoints used only by the Elaichi app itself (sign-in, consent screens, browser redirects, inbound webhooks) are not documented.'
servers:
- url: https://api.elaichi.ai
  description: Production
tags:
- name: Current user
paths:
  /user/me:
    get:
      operationId: getCurrentUser
      summary: Get the current user and their organizations
      tags:
      - Current user
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                allOf:
                - $ref: '#/components/schemas/User'
                - type: object
                  properties:
                    mfa_enabled:
                      type: boolean
                      description: True when TOTP is active on this account.
                    mfa_setup_required:
                      type: boolean
                      description: True when THIS session would be refused (`403 mfa_setup_required`) in at least one organization the user belongs to, because the organization requires a second factor and the session has not shown one. Always `false` for an API token. A client routes the person to second-factor setup on this rather than working out which organizations require one.
                    mfa_setup_required_org_ids:
                      type: array
                      items:
                        type: string
                      description: 'The organizations behind `mfa_setup_required`: a bounded page (at most 50), with the organization named by the `current_org_id` query parameter first when it is one of them. Not the whole set — `mfa_setup_required_org_count` is the true number; an organization not listed still refuses with `403 mfa_setup_required` when entered.'
                    mfa_setup_required_org_count:
                      type: integer
                      minimum: 0
                      description: How many organizations refuse this session for lack of a second factor.
                    can_disable_mfa:
                      type: boolean
                      description: '`false` while an organization the user belongs to requires a second factor and they hold no passkey — turning the authenticator app off (`DELETE /user/me/mfa/totp`) is refused with `409 mfa_required_by_organization`. The reason is in `mfa_disable_blocked_reason`.'
                    mfa_disable_blocked_reason:
                      type:
                      - string
                      - 'null'
                      description: A sentence saying why `can_disable_mfa` is `false`, or `null`.
                    is_root_org_staff:
                      type: boolean
                      description: True only for Elaichi support accounts. Always false for customer members.
                    organizations:
                      type: array
                      description: One entry per active membership. Organizations where membership has lapsed are omitted.
                      items:
                        type: object
                        properties:
                          organization:
                            $ref: '#/components/schemas/Organization'
                          member:
                            type: object
                            description: Membership facts only — roles and teams are the sibling fields below, not nested here.
                            properties:
                              user_id:
                                type: string
                                description: User id (`usr_…`).
                              status:
                                type: string
                              via:
                                type:
                                - string
                                - 'null'
                                description: How they joined, e.g. invite or verified domain.
                              joined_at:
                                type: string
                                format: date-time
                          roles:
                            type: array
                            description: Role summaries held in this organization.
                            items:
                              type: object
                              properties:
                                id:
                                  type: string
                                  description: Role id (`role_…`).
                                name:
                                  type: string
                                is_system:
                                  type: boolean
                                seat_class:
                                  type: string
                                  enum:
                                  - billable
                                  - free_admin
                          teams:
                            type: array
                            items:
                              type: object
                              properties:
                                id:
                                  type: string
                                  description: Team id (`team_…`).
                                name:
                                  type: string
                          permissions:
                            type: array
                            items:
                              type: string
                            description: Effective permission names, unioned across roles. This is the authoritative list for deciding what to show; the server re-checks it on every request.
                          unpaid_seat_charge:
                            type:
                            - object
                            - 'null'
                            description: 'The current organization only (`current_org_id`), and only when these permissions include `billing:view` (absent otherwise): null unless a seat-change invoice the card holder can act on is unpaid, including when the only unpaid ones are still with the bank. The newest such charge, as `unpaid_seat_charges.newest` on `GET /organization/{id}/billing`, plus `count` (every unpaid seat charge). The Elaichi app shows it as a bar on every page.'
                            properties:
                              state:
                                type: string
                                enum:
                                - failed
                                - needs_approval
                                - bank_approval
                              amount_due:
                                type:
                                - number
                                - 'null'
                                description: Major units of `currency`.
                              currency:
                                type:
                                - string
                                - 'null'
                              pay_url:
                                type:
                                - string
                                - 'null'
                                format: uri
                                description: Stripe's hosted invoice page; null for `bank_approval`.
                              since:
                                type: string
                                format: date-time
                              count:
                                type: integer
        '400':
          description: Bad request
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '401':
          description: Unauthorized
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '403':
          description: Forbidden
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '404':
          description: Not found
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '429':
          description: Rate limited
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
      description: 'Returns the current user and their organizations. The result is the profile of whoever the credential belongs to, plus one entry per organization they are an active member of, each carrying that org''s roles, teams and effective permissions. Call this first: it is how a client learns which organization ids it may put in `X-Organization-Id` and which actions to offer. With an org API token this still returns the token owner''s memberships, so read `organizations` rather than assuming the token''s org is the only one.'
      security:
      - bearerAuth: []
components:
  schemas:
    Organization:
      type: object
      properties:
        id:
          type: string
          description: Organization id (`org_…`) — the value for `X-Organization-Id`.
        name:
          type: string
        slug:
          type: string
          description: Immutable after creation.
        plan:
          type: string
          description: 'The stored plan: `personal`, `gold`, `black`, or `none` while on hold. This is not the same as the effective entitlement — read `GET /organization/{id}/entitlements` before gating a feature on it.'
        region:
          type:
          - string
          - 'null'
          description: 'Data location fixed at creation: `us`/`eu` pin a hard jurisdiction, `apac` is a placement hint.'
        trial_ends_at:
          type:
          - string
          - 'null'
          format: date-time
        trial_indefinite_at:
          type:
          - string
          - 'null'
          format: date-time
          description: 'Set when Elaichi granted this organization an indefinite trial, otherwise null. Unlocked with no end date: no countdown, no expiry email, billing still reachable.'
        settings:
          type: object
          additionalProperties: true
          description: Free-form org settings. `PATCH /organization/{id}` REPLACES this object wholesale.
        logo:
          type:
          - string
          - 'null'
          format: uri
          description: Public URL of the logo image, or null.
        can_delete:
          type: boolean
          description: 'Whether the caller may delete this organization: the `org:delete` permission, which only the Org Owner role holds. Server-computed, so branch on this rather than inspecting roles. Always `false` on rows that have no member context to compute it from, such as the organization list `GET /organization`. It never overstates: trust it when true, and read `GET /user/me` or `GET /organization/{id}` (both compute it) when you need it for a list row.'
        can_manage:
          type: boolean
          description: 'Whether the caller may change this organization''s settings: the `org:manage` permission that `PATCH /organization/{id}` requires, and the organization is neither suspended nor in its deletion grace period. Server-computed, and `false` wherever `can_delete` is false for lack of a member context; it never overstates.'
        allow_staff_impersonation:
          type: boolean
          description: Whether Elaichi support may sign in as this organization's members to help them. `true` by default. When `false`, every request made through such a support session against this organization is refused with `403 staff_impersonation_blocked`, reads included, and the organization is left out of that session's `GET /user/me` and `GET /organization`. Changed with `PATCH /organization/{id}` (`org:manage`).
        mfa_required:
          type: boolean
          description: 'Whether members must hold a second factor to act in this organization. `false` by default. When `true`, a signed-in session that has not shown a second factor (no TOTP challenge at login, no passkey sign-in, no factor enrolled since) is refused on every organization-scoped route, reads included, with `403 mfa_setup_required`; `error.details.has_second_factor` says whether the person already has one and only needs to sign in with it. Exempt: org API tokens, Elaichi support sessions, and a session signed in through this organization''s own SSO connection. MCP connections made before it was switched on, or from a session without a factor, are refused until the person connects again. Turning it off only lifts the organization requirement: a member who set up an authenticator app of their own is still challenged for it at every non-passkey sign-in. Changed with `PATCH /organization/{id}` (`org:manage`, interactive session only).'
        can_require_mfa:
          type: boolean
          description: 'Whether the CALLER may turn `mfa_required` ON right now: `can_manage`, from an interactive session that would itself pass the check it is about to create. `false` — with the reason in `can_require_mfa_reason` — when switching it on would lock the caller out of this organization. The PATCH refuses that regardless with `409 mfa_setup_required`. Turning it OFF is not governed by this field; it needs a step-up.'
        can_require_mfa_reason:
          type:
          - string
          - 'null'
          description: A sentence saying why `can_require_mfa` is `false` for a caller who can otherwise manage the organization. `null` otherwise.
        deletion_scheduled_at:
          type:
          - string
          - 'null'
          format: date-time
          description: Set when a deletion has been scheduled (`DELETE /organization/{id}`). The organization is read-only until `purge_after`. Null otherwise.
        purge_after:
          type:
          - string
          - 'null'
          format: date-time
          description: When a scheduled deletion becomes permanent — 30 days after `deletion_scheduled_at`. Null unless scheduled.
        can_restore:
          type: boolean
          description: 'Whether the caller may cancel a scheduled deletion: the `org:manage` permission, and only while `purge_after` is still ahead. Server-computed like `can_delete`, and `false` on rows with no member context. Read `purge_after` to tell "too late" from "not yours to undo".'
        can_authorize_apps:
          type: boolean
          description: 'Whether the CALLER may connect an app (MCP OAuth consent) to this organization right now: `false` while it is suspended, scheduled for deletion, has no active plan, or is on Personal and the caller is not its primary owner. Server-computed by the same gate `POST /oauth/authorize-request/{id}/approve` calls; present only on member-scoped responses. `authorize_apps_blocked_reason` says which.'
        authorize_apps_blocked_reason:
          type:
          - string
          - 'null'
          enum:
          - blocked
          - pending_deletion
          - no_plan
          - plan_single_user
          - null
          description: 'Why `can_authorize_apps` is `false`, in the gate''s own order: `blocked`, then `pending_deletion` (even when the subscription is also gone, since a soft delete cancels it), then `no_plan`, then `plan_single_user` (Personal admits only the primary owner). `null` when connecting is open.'
        created_at:
          type: string
          format: date-time
        updated_at:
          type: string
          format: date-time
    Error:
      type: object
      required:
      - error
      description: The Elaichi error envelope. The MCP OAuth endpoints under `/oauth` are the exception — they return RFC 6749 errors instead (see `OAuthError`).
      properties:
        error:
          type: object
          required:
          - message
          - code
          properties:
            message:
              type: string
              description: Human-readable. 5xx messages are deliberately generic.
            code:
              type: string
              description: Stable machine-readable code, e.g. `not_found`, `subscription_required`.
            details:
              description: Structured detail for codes that carry one, e.g. `toolboxes_need_resolution`.
            feature:
              type: string
              description: The gated feature, on entitlement failures.
            plan:
              type:
              - string
              - 'null'
              enum:
              - personal
              - gold
              - black
              - null
          additionalProperties: true
    User:
      type: object
      properties:
        id:
          type: string
          description: User id (`usr_…`).
        email:
          type: string
          format: email
        name:
          type:
          - string
          - 'null'
        avatar_url:
          type:
          - string
          - 'null'
        identities:
          type: array
          description: Login identities linked to this account.
          items:
            type: object
            properties:
              provider:
                type: string
                description: e.g. `google`, `email_code`, `invite`, or an SSO connection.
              connected_at:
                type: string
                format: date-time
        is_active:
          type: boolean
          description: Inactive accounts cannot authenticate at all.
        is_staff:
          type: boolean
          description: True only for Elaichi support accounts. Always false for customer members; unrelated to organization roles.
        last_login_at:
          type:
          - string
          - 'null'
          format: date-time
        created_at:
          type: string
          format: date-time
        updated_at:
          type: string
          format: date-time
  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer
      bearerFormat: session or API token
      description: '`Authorization: Bearer <token>` with an org-scoped API token (`elch_{org_id}_{64 hex}`), created in the Elaichi app under Settings → API tokens. The Elaichi app itself signs in with a session cookie, which is also accepted but is not meant for integrations. Two other credential families exist and are NOT interchangeable with this one: an MCP OAuth access token (`POST /mcp` only) and a SCIM token (`/scim/v2/*` only).'
    mcpOAuth:
      type: oauth2
      description: MCP OAuth access token, used only by `POST /mcp` — not interchangeable with `bearerAuth`. Discovered per RFC 9728/8414 at `/.well-known/oauth-protected-resource` and `/.well-known/oauth-authorization-server`.
      flows:
        authorizationCode:
          authorizationUrl: https://api.elaichi.ai/oauth/authorize
          tokenUrl: https://api.elaichi.ai/oauth/token
          scopes:
            mcp:read: Anything you can already see in Elaichi. Never secret values. It can also ask an admin for access to something restricted for you.
            mcp:write: Create and change teams, roles, toolboxes, templates and connections, and share access.
            mcp:destructive: Permanently delete data and remove access in Elaichi. This cannot be undone.
            mcp:tools: Run tools from the toolboxes you choose next, deleting in your connected apps included. It can also ask an admin for access to something restricted for you.
            openid: That you are signed in, and the user ID we use for you. Nothing else.
            email: Your email address, and whether it is verified. Apps use this to check your domain.