Eden AI Organization Management API

The management plane: an issuer key mints scoped worker keys, worker keys mint, rotate and revoke inference keys, and manage-scoped reads cover members, IdP-synced groups and organization usage. 16 operations, scoped by manage:read / manage:write / manage:mint.

Operations 16

GET /manage/auth-keys/ #
POST /manage/auth-keys/ #
DELETE /manage/auth-keys/{key_id}/ #
GET /manage/groups/ #
GET /manage/groups/{external_group_id}/ #
GET /manage/keys/ #
POST /manage/keys/ #
GET /manage/keys/{key_id}/ #
PATCH /manage/keys/{key_id}/ #
DELETE /manage/keys/{key_id}/ #
POST /manage/keys/{key_id}/rotate/ #
GET /manage/keys/{key_id}/usage/ #
GET /manage/members/ #
PATCH /manage/members/{email}/role/ #
GET /manage/usage/ #
GET /manage/whoami/ #

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/eden-ai-organization-management-api"
All apis
curl "https://apis.io/api/v1/apis?limit=25"

Discovery needs no key. Ratings and market analysis are Pro.

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

eden-ai-organization-management-openapi.json Raw ↑
{
    "openapi": "3.0.3",
    "info": {
        "title": "Organization Management",
        "version": "2.0",
        "description": "Your project description"
    },
    "paths": {
        "/manage/auth-keys/": {
            "get": {
                "operationId": "manage_auth_keys_retrieve",
                "description": "List the org's management keys (issuer + worker), never their secrets. ``manage:mint``.",
                "tags": [
                    "auth-keys"
                ],
                "responses": {
                    "200": {
                        "description": "No response body"
                    }
                }
            },
            "post": {
                "operationId": "manage_auth_keys_create",
                "description": "``POST /v3/manage/auth-keys`` (manage:mint) -- an ISSUER key mints a new WORKER\n(manage:read/manage:write) key for its own org; the secret is shown ONCE. This is the\nprogrammatic middle of the service->auth->inference chain: an issuer key (born once from the\nowner-authed dashboard) mints short-lived working keys with no human in the loop, which in turn\nmint inference keys via ``POST /manage/keys``.\n\nA minted key can NEVER carry ``manage:mint`` -- an issuer cannot mint another issuer\n(no self-propagation); issuer keys are born only from the session-authed, owner-only dashboard\nendpoint. Enforced twice: the serializer's ``allowed_scopes`` restricts this endpoint to\nread/write, and ``validate_scopes`` on the model rejects any mint/worker mix regardless.",
                "tags": [
                    "auth-keys"
                ],
                "responses": {
                    "200": {
                        "description": "No response body"
                    }
                }
            }
        },
        "/manage/auth-keys/{key_id}/": {
            "delete": {
                "operationId": "manage_auth_keys_destroy",
                "description": "``DELETE /v3/manage/auth-keys/{key_id}`` (``manage:mint``) -- an issuer revokes a WORKER key it\nmanages (terminal, idempotent). Refuses an ISSUER-key target: issuer keys are born and killed only\nfrom the owner-authed dashboard, mirroring the no-self-propagation rule on mint. Org-scoped: a\nkey_id outside the issuer's org is a 404.",
                "parameters": [
                    {
                        "in": "path",
                        "name": "key_id",
                        "schema": {
                            "type": "string",
                            "format": "uuid"
                        },
                        "required": true
                    }
                ],
                "tags": [
                    "auth-keys"
                ],
                "responses": {
                    "204": {
                        "description": "No response body"
                    }
                }
            }
        },
        "/manage/groups/": {
            "get": {
                "operationId": "manage_groups_list",
                "description": "``GET /v3/manage/groups`` -- the org's IdP-synced directory groups and their members, ordered\nby name for a stable page. ``manage:read``, org-scoped. Read-only in v1 (see module docstring).",
                "parameters": [
                    {
                        "name": "limit",
                        "required": false,
                        "in": "query",
                        "description": "Number of results to return per page.",
                        "schema": {
                            "type": "integer"
                        }
                    },
                    {
                        "name": "offset",
                        "required": false,
                        "in": "query",
                        "description": "The initial index from which to return the results.",
                        "schema": {
                            "type": "integer"
                        }
                    }
                ],
                "tags": [
                    "groups"
                ],
                "responses": {
                    "200": {
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/PaginatedManageGroupList"
                                }
                            }
                        },
                        "description": ""
                    }
                }
            }
        },
        "/manage/groups/{external_group_id}/": {
            "get": {
                "operationId": "manage_groups_retrieve",
                "description": "``GET /v3/manage/groups/{external_group_id}`` -- one IdP-synced group and its members, for\nlist+detail parity with ``/keys``. ``manage:read``, org-scoped: a group id not in the calling key's\norg is a 404, never another org's group. Addressed by ``external_group_id`` (the IdP id), like the\nlist; the internal PK is never exposed. ``external_group_id`` is unique per org\n(``unique_together`` with ``organization`` on the model), so the org-scoped lookup matches at most\none row -- ``get_object`` cannot raise ``MultipleObjectsReturned``.",
                "parameters": [
                    {
                        "in": "path",
                        "name": "external_group_id",
                        "schema": {
                            "type": "string"
                        },
                        "required": true
                    }
                ],
                "tags": [
                    "groups"
                ],
                "responses": {
                    "200": {
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/ManageGroup"
                                }
                            }
                        },
                        "description": ""
                    }
                }
            }
        },
        "/manage/keys/": {
            "get": {
                "operationId": "manage_keys_list",
                "description": "``GET /v3/manage/keys`` (list, ``manage:read``) and ``POST /v3/manage/keys`` (mint an inference\nkey, ``manage:write``). Org-scoped through ``principals_in_org``. Balance is pending-adjusted per\npage on the list; the created secret is returned ONCE in the 201 and never by a read.",
                "parameters": [
                    {
                        "name": "limit",
                        "required": false,
                        "in": "query",
                        "description": "Number of results to return per page.",
                        "schema": {
                            "type": "integer"
                        }
                    },
                    {
                        "name": "offset",
                        "required": false,
                        "in": "query",
                        "description": "The initial index from which to return the results.",
                        "schema": {
                            "type": "integer"
                        }
                    }
                ],
                "tags": [
                    "keys"
                ],
                "responses": {
                    "200": {
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/PaginatedManagementKeyList"
                                }
                            }
                        },
                        "description": ""
                    }
                }
            },
            "post": {
                "operationId": "manage_keys_create",
                "description": "``GET /v3/manage/keys`` (list, ``manage:read``) and ``POST /v3/manage/keys`` (mint an inference\nkey, ``manage:write``). Org-scoped through ``principals_in_org``. Balance is pending-adjusted per\npage on the list; the created secret is returned ONCE in the 201 and never by a read.",
                "tags": [
                    "keys"
                ],
                "requestBody": {
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/ManagementKeyRequest"
                            }
                        },
                        "application/x-www-form-urlencoded": {
                            "schema": {
                                "$ref": "#/components/schemas/ManagementKeyRequest"
                            }
                        },
                        "multipart/form-data": {
                            "schema": {
                                "$ref": "#/components/schemas/ManagementKeyRequest"
                            }
                        }
                    },
                    "required": true
                },
                "responses": {
                    "201": {
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/ManagementKey"
                                }
                            }
                        },
                        "description": ""
                    }
                }
            }
        },
        "/manage/keys/{key_id}/": {
            "get": {
                "operationId": "manage_keys_retrieve",
                "description": "``GET`` (read), ``PATCH`` (write, policy fields + rename), ``DELETE`` (write, IRREVERSIBLE revoke)\nfor one key at ``/v3/manage/keys/{key_id}``, org-scoped: a ``key_id`` not in the calling key's org\nis a 404, not another org's key. DELETE destroys the secret and keeps the row marked revoked (see\n``destroy``); there is no re-enable. Balance is pending-adjusted. Never returns the secret or its hash.",
                "parameters": [
                    {
                        "in": "path",
                        "name": "key_id",
                        "schema": {
                            "type": "string",
                            "format": "uuid"
                        },
                        "required": true
                    }
                ],
                "tags": [
                    "keys"
                ],
                "responses": {
                    "200": {
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/ManagementKey"
                                }
                            }
                        },
                        "description": ""
                    }
                }
            },
            "patch": {
                "operationId": "manage_keys_partial_update",
                "description": "``GET`` (read), ``PATCH`` (write, policy fields + rename), ``DELETE`` (write, IRREVERSIBLE revoke)\nfor one key at ``/v3/manage/keys/{key_id}``, org-scoped: a ``key_id`` not in the calling key's org\nis a 404, not another org's key. DELETE destroys the secret and keeps the row marked revoked (see\n``destroy``); there is no re-enable. Balance is pending-adjusted. Never returns the secret or its hash.",
                "parameters": [
                    {
                        "in": "path",
                        "name": "key_id",
                        "schema": {
                            "type": "string",
                            "format": "uuid"
                        },
                        "required": true
                    }
                ],
                "tags": [
                    "keys"
                ],
                "requestBody": {
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/PatchedManagementKeyRequest"
                            }
                        },
                        "application/x-www-form-urlencoded": {
                            "schema": {
                                "$ref": "#/components/schemas/PatchedManagementKeyRequest"
                            }
                        },
                        "multipart/form-data": {
                            "schema": {
                                "$ref": "#/components/schemas/PatchedManagementKeyRequest"
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/ManagementKey"
                                }
                            }
                        },
                        "description": ""
                    }
                }
            },
            "delete": {
                "operationId": "manage_keys_destroy",
                "description": "``GET`` (read), ``PATCH`` (write, policy fields + rename), ``DELETE`` (write, IRREVERSIBLE revoke)\nfor one key at ``/v3/manage/keys/{key_id}``, org-scoped: a ``key_id`` not in the calling key's org\nis a 404, not another org's key. DELETE destroys the secret and keeps the row marked revoked (see\n``destroy``); there is no re-enable. Balance is pending-adjusted. Never returns the secret or its hash.",
                "parameters": [
                    {
                        "in": "path",
                        "name": "key_id",
                        "schema": {
                            "type": "string",
                            "format": "uuid"
                        },
                        "required": true
                    }
                ],
                "tags": [
                    "keys"
                ],
                "responses": {
                    "204": {
                        "description": "No response body"
                    }
                }
            }
        },
        "/manage/keys/{key_id}/rotate/": {
            "post": {
                "operationId": "manage_keys_rotate_create",
                "description": "``POST /v3/manage/keys/{key_id}/rotate`` (manage:write) -- replace a key's secret in place: same\nidentity (name, key_id, budget, guardrail), a brand-new ``sk-eden`` value returned ONCE. Lets a\ncompliance pipeline roll a secret without reconfiguring the key. Distinct from DELETE: revoke KILLS\n(terminal), rotate RE-SECRETS.\n\nA REVOKED key is a 404 here, never resurrected. ``rotate_key_secret`` clears ``revoked_at`` and\nwrites fresh secret material, so rotating a revoked key would REVIVE it -- the exact one-way-door\nthat revoke depends on. The read filters a revoked (or cross-org, or unknown) key_id to a 404, and\nthe whole rotate runs in a transaction that ``select_for_update``-locks the row: a concurrent DELETE\neither commits its revoke first (``revoked_at`` then filters the row out -> 404) or blocks on the\nlock until the rotate commits and then still wins its own compare-and-set. Without the lock the read\nfilter alone is a check-then-act race -- a rotate that resolved a live key could blind-write a fresh\nsecret AFTER a concurrent revoke landed, resurrecting a terminally-revoked key. So revocation stays\nterminal.",
                "parameters": [
                    {
                        "in": "path",
                        "name": "key_id",
                        "schema": {
                            "type": "string",
                            "format": "uuid"
                        },
                        "required": true
                    }
                ],
                "tags": [
                    "keys"
                ],
                "responses": {
                    "200": {
                        "description": "No response body"
                    }
                }
            }
        },
        "/manage/keys/{key_id}/usage/": {
            "get": {
                "operationId": "manage_keys_usage_retrieve",
                "description": "``GET /v3/manage/keys/{key_id}/usage`` -- usage for one key, filtered by ``custom_token``\nIDENTITY (precise, unlike the dashboard's name filter). A ``key_id`` not in the org is a 404.\nTime-series only. ``manage:read``.",
                "parameters": [
                    {
                        "in": "path",
                        "name": "key_id",
                        "schema": {
                            "type": "string",
                            "format": "uuid"
                        },
                        "required": true
                    }
                ],
                "tags": [
                    "keys"
                ],
                "responses": {
                    "200": {
                        "description": "No response body"
                    }
                }
            }
        },
        "/manage/members/": {
            "get": {
                "operationId": "manage_members_list",
                "description": "``GET /v3/manage/members`` — the org's active members and owner. Reuses the\ndashboard's ``OrganisationUsersSerializer`` and the one ``principals_in_org``\ndefinition, so the management plane and the dashboard cannot disagree on who is a\nmember. Ordered by email for a stable page across requests.",
                "parameters": [
                    {
                        "name": "limit",
                        "required": false,
                        "in": "query",
                        "description": "Number of results to return per page.",
                        "schema": {
                            "type": "integer"
                        }
                    },
                    {
                        "name": "offset",
                        "required": false,
                        "in": "query",
                        "description": "The initial index from which to return the results.",
                        "schema": {
                            "type": "integer"
                        }
                    }
                ],
                "tags": [
                    "members"
                ],
                "responses": {
                    "200": {
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/PaginatedOrganisationUsersList"
                                }
                            }
                        },
                        "description": ""
                    }
                }
            }
        },
        "/manage/members/{email}/role/": {
            "patch": {
                "operationId": "manage_members_role_partial_update",
                "description": "``PATCH /v3/manage/members/{email}/role`` -- set a member's RBAC role. ``manage:write``,\norg-scoped: the member must be a principal of the calling key's org (else 404). The org owner's\nrole is immutable. Audited (actor = the management key). Returns the updated member in the same\nrepresentation as GET /manage/members.",
                "parameters": [
                    {
                        "in": "path",
                        "name": "email",
                        "schema": {
                            "type": "string"
                        },
                        "required": true
                    }
                ],
                "tags": [
                    "members"
                ],
                "responses": {
                    "200": {
                        "description": "No response body"
                    }
                }
            }
        },
        "/manage/usage/": {
            "get": {
                "operationId": "manage_usage_retrieve",
                "description": "``GET /v3/manage/usage`` -- organization usage aggregated over History, scoped to the calling\nkey's org (``principals_in_org``). ``manage:read``. ``end`` is exclusive at day granularity; see the\nmodule docstring for the parameter and envelope contract.",
                "tags": [
                    "usage"
                ],
                "responses": {
                    "200": {
                        "description": "No response body"
                    }
                }
            }
        },
        "/manage/whoami/": {
            "get": {
                "operationId": "manage_whoami_retrieve",
                "description": "``GET /v3/manage/whoami`` — the calling key's own organization, scopes and\nexpiry. Requires only a valid management key (no scope), which is enough to prove\nthe auth path end to end. Never returns the secret, its hash, or last4.",
                "tags": [
                    "whoami"
                ],
                "responses": {
                    "200": {
                        "description": "No response body"
                    }
                }
            }
        }
    },
    "components": {
        "schemas": {
            "ManageGroup": {
                "type": "object",
                "description": "A directory-synced group as the management plane exposes it: the stable IdP identifiers plus\nthe member emails. The internal PK is not exposed; ``external_group_id`` is the addressable id.",
                "properties": {
                    "external_group_id": {
                        "type": "string",
                        "maxLength": 255
                    },
                    "name": {
                        "type": "string",
                        "maxLength": 255
                    },
                    "members": {
                        "type": "string",
                        "readOnly": true
                    }
                },
                "required": [
                    "external_group_id",
                    "members",
                    "name"
                ]
            },
            "ManagementKey": {
                "type": "object",
                "description": "An org's inference key as the management plane exposes it. Never the secret or\nits hash — only non-secret metadata, addressed by the stable ``key_id`` (``id``).\n\n``balance`` is the pending-adjusted LIVE sub-limit, not the raw settled column.\nFor a credit-ledger-enrolled org the stored ``Token.balance`` lags by whatever the\nbatched rollup has not settled, so a management admin must be shown available, not\nsettled (the shipped display-vs-accounting doctrine, mirrored from\n``utils/check_credits.py`` and ``manage_user_account_serializers``). The un-settled\ndeltas (≤ 0, so they ADD) are batch-fetched once per page by the view and passed in\n``context[\"pending\"]``; a non-ledger org simply has none, so the add is a no-op.\n\n``id`` is null for an un-migrated legacy key (one still stored as a JWT, no\n``key_id`` yet); such a key is listed but not addressable via ``/keys/{id}`` until\nit is regenerated onto the hashed scheme.",
                "properties": {
                    "id": {
                        "type": "string",
                        "format": "uuid",
                        "readOnly": true
                    },
                    "name": {
                        "type": "string",
                        "description": "The token name",
                        "maxLength": 200
                    },
                    "token_type": {
                        "$ref": "#/components/schemas/TokenTypeEnum"
                    },
                    "member": {
                        "type": "string",
                        "format": "email",
                        "readOnly": true
                    },
                    "masked": {
                        "type": "string",
                        "readOnly": true
                    },
                    "active_balance": {
                        "type": "boolean",
                        "description": "Weither to use the balance field or not."
                    },
                    "balance": {
                        "type": "string",
                        "readOnly": true
                    },
                    "expire_time": {
                        "type": "string",
                        "format": "date-time",
                        "nullable": true
                    },
                    "revoked": {
                        "type": "boolean",
                        "readOnly": true
                    },
                    "revoked_at": {
                        "type": "string",
                        "format": "date-time",
                        "nullable": true
                    }
                },
                "required": [
                    "balance",
                    "id",
                    "masked",
                    "member",
                    "name",
                    "revoked"
                ]
            },
            "ManagementKeyRequest": {
                "type": "object",
                "description": "An org's inference key as the management plane exposes it. Never the secret or\nits hash — only non-secret metadata, addressed by the stable ``key_id`` (``id``).\n\n``balance`` is the pending-adjusted LIVE sub-limit, not the raw settled column.\nFor a credit-ledger-enrolled org the stored ``Token.balance`` lags by whatever the\nbatched rollup has not settled, so a management admin must be shown available, not\nsettled (the shipped display-vs-accounting doctrine, mirrored from\n``utils/check_credits.py`` and ``manage_user_account_serializers``). The un-settled\ndeltas (≤ 0, so they ADD) are batch-fetched once per page by the view and passed in\n``context[\"pending\"]``; a non-ledger org simply has none, so the add is a no-op.\n\n``id`` is null for an un-migrated legacy key (one still stored as a JWT, no\n``key_id`` yet); such a key is listed but not addressable via ``/keys/{id}`` until\nit is regenerated onto the hashed scheme.",
                "properties": {
                    "name": {
                        "type": "string",
                        "minLength": 1,
                        "description": "The token name",
                        "maxLength": 200
                    },
                    "token_type": {
                        "$ref": "#/components/schemas/TokenTypeEnum"
                    },
                    "active_balance": {
                        "type": "boolean",
                        "description": "Weither to use the balance field or not."
                    },
                    "expire_time": {
                        "type": "string",
                        "format": "date-time",
                        "nullable": true
                    },
                    "revoked_at": {
                        "type": "string",
                        "format": "date-time",
                        "nullable": true
                    }
                },
                "required": [
                    "name"
                ]
            },
            "OrganisationUsers": {
                "type": "object",
                "properties": {
                    "email": {
                        "type": "string",
                        "format": "email",
                        "nullable": true,
                        "maxLength": 500
                    },
                    "fullname": {
                        "type": "string",
                        "pattern": "^[a-zA-Z\\'\\- ]+$",
                        "maxLength": 60
                    },
                    "is_confirmed": {
                        "type": "boolean"
                    },
                    "role": {
                        "type": "string",
                        "readOnly": true
                    },
                    "guardrail": {
                        "type": "string",
                        "readOnly": true
                    },
                    "effective_rate_limit": {
                        "type": "string",
                        "readOnly": true
                    },
                    "tokens": {
                        "type": "string",
                        "readOnly": true
                    },
                    "is_org_owner": {
                        "type": "boolean",
                        "readOnly": true
                    },
                    "directory_groups": {
                        "type": "string",
                        "readOnly": true
                    }
                },
                "required": [
                    "directory_groups",
                    "effective_rate_limit",
                    "fullname",
                    "guardrail",
                    "is_org_owner",
                    "role",
                    "tokens"
                ]
            },
            "PaginatedManageGroupList": {
                "type": "object",
                "required": [
                    "count",
                    "results"
                ],
                "properties": {
                    "count": {
                        "type": "integer",
                        "example": 123
                    },
                    "next": {
                        "type": "string",
                        "nullable": true,
                        "format": "uri",
                        "example": "http://api.example.org/accounts/?offset=400&limit=100"
                    },
                    "previous": {
                        "type": "string",
                        "nullable": true,
                        "format": "uri",
                        "example": "http://api.example.org/accounts/?offset=200&limit=100"
                    },
                    "results": {
                        "type": "array",
                        "items": {
                            "$ref": "#/components/schemas/ManageGroup"
                        }
                    }
                }
            },
            "PaginatedManagementKeyList": {
                "type": "object",
                "required": [
                    "count",
                    "results"
                ],
                "properties": {
                    "count": {
                        "type": "integer",
                        "example": 123
                    },
                    "next": {
                        "type": "string",
                        "nullable": true,
                        "format": "uri",
                        "example": "http://api.example.org/accounts/?offset=400&limit=100"
                    },
                    "previous": {
                        "type": "string",
                        "nullable": true,
                        "format": "uri",
                        "example": "http://api.example.org/accounts/?offset=200&limit=100"
                    },
                    "results": {
                        "type": "array",
                        "items": {
                            "$ref": "#/components/schemas/ManagementKey"
                        }
                    }
                }
            },
            "PaginatedOrganisationUsersList": {
                "type": "object",
                "required": [
                    "count",
                    "results"
                ],
                "properties": {
                    "count": {
                        "type": "integer",
                        "example": 123
                    },
                    "next": {
                        "type": "string",
                        "nullable": true,
                        "format": "uri",
                        "example": "http://api.example.org/accounts/?offset=400&limit=100"
                    },
                    "previous": {
                        "type": "string",
                        "nullable": true,
                        "format": "uri",
                        "example": "http://api.example.org/accounts/?offset=200&limit=100"
                    },
                    "results": {
                        "type": "array"

# --- truncated at 32 KB (34 KB total) ---
# Full source: https://raw.githubusercontent.com/api-evangelist/eden-ai/refs/heads/main/openapi/_original/eden-ai-organization-management-openapi.json