OpenRelay Organizations API
Organizations and their members. Most resources are scoped to an org.
Organizations and their members. Most resources are scoped to an org.
Every API here is available over the APIs.io API and to AI agents over MCP.
One button, every client — Claude, Cursor, VS Code and the rest.
https://apis.io/mcp
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.curl "https://apis.io/api/v1/apis/openrelay-organizations-api"
curl "https://apis.io/api/v1/apis?limit=25"
Discovery needs no key. Ratings and market analysis are Pro.
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: 3.2.0
info:
description: 'The OpenRelay control-plane REST API. Deploy GPU VMs and inference clusters, manage organizations and billing, and automate your infrastructure. All requests are authenticated with an API key (`vl_…`) unless noted otherwise.
'
title: OpenRelay Account Organizations API
version: 0.1.0
servers:
- description: Production
url: https://api.openrelay.inc
- description: Beta
url: https://api.beta.openrelay.inc
- description: Local development
url: http://localhost:8083
tags:
- description: Organizations and their members. Most resources are scoped to an org.
name: Organizations
paths:
/v1/orgs:
post:
description: Requires a signed-in dashboard session token; API keys cannot call this endpoint.
operationId: createOrg
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/CreateOrgRequest'
required: true
responses:
'200':
content:
application/json:
schema:
$ref: '#/components/schemas/BootstrapResult'
description: Created (caller is owner)
'401':
$ref: '#/components/responses/Unauthorized'
'409':
$ref: '#/components/responses/Conflict'
security:
- apiKey: []
summary: Create an organization (caller becomes owner)
tags:
- Organizations
x-openrelay-cli:
hidden: true
x-openrelay-mcp:
exclude: true
/v1/orgs/{orgId}:
get:
operationId: getOrg
parameters:
- in: path
name: orgId
required: true
schema:
type: string
responses:
'200':
content:
application/json:
schema:
$ref: '#/components/schemas/Organization'
description: The organization
'401':
$ref: '#/components/responses/Unauthorized'
'403':
$ref: '#/components/responses/Forbidden'
'404':
$ref: '#/components/responses/NotFound'
security:
- apiKey: []
summary: Get an organization
tags:
- Organizations
patch:
operationId: updateOrg
parameters:
- in: path
name: orgId
required: true
schema:
type: string
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/UpdateOrgRequest'
required: true
responses:
'200':
content:
application/json:
schema:
$ref: '#/components/schemas/Organization'
description: Updated
'401':
$ref: '#/components/responses/Unauthorized'
'403':
$ref: '#/components/responses/Forbidden'
'404':
$ref: '#/components/responses/NotFound'
security:
- apiKey: []
summary: Update an organization (owner/admin)
tags:
- Organizations
/v1/orgs/{orgId}/invites:
get:
operationId: listOrgInvites
parameters:
- in: path
name: orgId
required: true
schema:
type: string
responses:
'200':
content:
application/json:
schema:
items:
$ref: '#/components/schemas/Invite'
type: array
description: Pending invites
'401':
$ref: '#/components/responses/Unauthorized'
'403':
$ref: '#/components/responses/Forbidden'
security:
- apiKey: []
summary: List an org's pending invites (owner/admin)
tags:
- Organizations
/v1/orgs/{orgId}/invites/{email}:
delete:
operationId: revokeOrgInvite
parameters:
- in: path
name: orgId
required: true
schema:
type: string
- in: path
name: email
required: true
schema:
type: string
responses:
'204':
description: Revoked
'401':
$ref: '#/components/responses/Unauthorized'
'403':
$ref: '#/components/responses/Forbidden'
security:
- apiKey: []
summary: Revoke a pending invite (owner/admin)
tags:
- Organizations
x-openrelay-mcp:
destructiveHint: true
/v1/orgs/{orgId}/members:
get:
operationId: listOrgMembers
parameters:
- in: path
name: orgId
required: true
schema:
type: string
responses:
'200':
content:
application/json:
schema:
items:
$ref: '#/components/schemas/Member'
type: array
description: Members
'401':
$ref: '#/components/responses/Unauthorized'
'403':
$ref: '#/components/responses/Forbidden'
security:
- apiKey: []
summary: List an org's members
tags:
- Organizations
/v1/orgs/{orgId}/members/add:
post:
description: Records a pending invite and emails the address. The response status is always "invited"; the user becomes a member only after they accept (POST /v1/me/invites/{orgId}/accept). Re-inviting the same email refreshes the invite's role and expiry. 409 if the email already belongs to a member.
operationId: addOrgMember
parameters:
- in: path
name: orgId
required: true
schema:
type: string
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/AddMemberRequest'
required: true
responses:
'200':
content:
application/json:
schema:
$ref: '#/components/schemas/Member'
description: Added
'400':
$ref: '#/components/responses/BadRequest'
'401':
$ref: '#/components/responses/Unauthorized'
'403':
$ref: '#/components/responses/Forbidden'
'404':
$ref: '#/components/responses/NotFound'
'409':
$ref: '#/components/responses/Conflict'
security:
- apiKey: []
summary: Invite a member by email (owner/admin)
tags:
- Organizations
/v1/orgs/{orgId}/members/{userId}:
delete:
operationId: removeOrgMember
parameters:
- in: path
name: orgId
required: true
schema:
type: string
- in: path
name: userId
required: true
schema:
type: string
responses:
'204':
description: Removed
'401':
$ref: '#/components/responses/Unauthorized'
'403':
$ref: '#/components/responses/Forbidden'
security:
- apiKey: []
summary: Remove a member (owner/admin)
tags:
- Organizations
x-openrelay-mcp:
destructiveHint: true
patch:
operationId: updateOrgMemberRole
parameters:
- in: path
name: orgId
required: true
schema:
type: string
- in: path
name: userId
required: true
schema:
type: string
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/UpdateMemberRoleRequest'
required: true
responses:
'200':
content:
application/json:
schema:
$ref: '#/components/schemas/Member'
description: Updated
'400':
$ref: '#/components/responses/BadRequest'
'401':
$ref: '#/components/responses/Unauthorized'
'403':
$ref: '#/components/responses/Forbidden'
'404':
$ref: '#/components/responses/NotFound'
security:
- apiKey: []
summary: Update a member's role (owner/admin)
tags:
- Organizations
components:
schemas:
Error:
properties:
code:
type: string
error:
type: string
required:
- error
type: object
Member:
properties:
avatarUrl:
type: string
email:
type: string
fullName:
type: string
invitedAt:
type: string
joinedAt:
type: string
role:
type: string
status:
enum:
- active
- invited
type: string
userId:
type: string
required:
- userId
- role
type: object
AddMemberRequest:
properties:
email:
type: string
role:
enum:
- admin
- member
- viewer
type: string
required:
- email
- role
type: object
UpdateMemberRoleRequest:
properties:
role:
enum:
- owner
- admin
- member
- viewer
type: string
required:
- role
type: object
Organization:
properties:
billingEmail:
type: string
createdAt:
type: string
id:
type: string
isProvider:
type: boolean
name:
type: string
plan:
type: string
shortId:
type: string
slug:
type: string
required:
- id
- shortId
- name
- slug
- billingEmail
- plan
type: object
BootstrapResult:
properties:
organizationId:
type: string
role:
type: string
required:
- organizationId
- role
type: object
CreateOrgRequest:
properties:
billingEmail:
type: string
name:
type: string
slug:
type: string
required:
- name
type: object
UpdateOrgRequest:
properties:
billingEmail:
type: string
name:
type: string
type: object
Invite:
properties:
email:
type: string
expiresAt:
description: RFC3339; the invite cannot be accepted after this time. Re-invite to refresh.
type: string
invitedAt:
type: string
invitedBy:
type: string
role:
type: string
required:
- email
- role
- invitedAt
type: object
responses:
NotFound:
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
description: Resource not found
Forbidden:
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
description: API key lacks the required scope
BadRequest:
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
description: The request is invalid
Conflict:
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
description: The request conflicts with existing state
Unauthorized:
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
description: Missing or invalid API key
securitySchemes:
apiKey:
description: 'OpenRelay API key. Send it as `Authorization: Bearer vl_…`.'
scheme: bearer
type: http