Create an integration
/api/v1/organizations/{id}/oauth-clientsCreates a machine OAuth client owned by the organization and pinned to it, with the client_credentials grant and the permissions scope. Its tokens name the organization and the Environment's default audience. The client_secret is returned in this response only. Refused while the Environment has no default audience (409 organization.integration_audience_missing), once the organization holds as many as it may (409 organization.integration_limit), for a name another of its integrations has (409 organization.integration_name_taken), and past the plan's machine-credential allowance (409 plan_limit_exceeded).
Authentication
Authorization Option A JWT access token. Never send alongside X-API-Key: a request carrying both is refused.
X-API-Key Option B API key for management-tier access. Never send alongside an Authorization header: a request carrying both is refused.
Path Parameters
idstring Required Request body
application/json
namestring Required Its name, unique among the organization's integrations.
Responses
application/json
data *OrganizationIntegrationCreatedResponseDto
application/json
error *ApiErrorBodyDto
application/json
error *ApiErrorBodyDto
application/json
error *ApiErrorBodyDto
application/json
error *ApiErrorBodyDto
application/json
error *ApiErrorBodyDto
Errors
When the request can't be completed, the response body includes a stable error code you can branch on, and a correlation_id (also sent as the X-Correlation-Id header). Quote the correlation id when you contact support: it identifies the exact request in Canopy's logs.
organization.integrations_disabledForbiddenThe Environment does not let organizations create integrations: <code>organization_integrations_enabled</code> is off, which it is by default. Every route under <code>/api/v1/organizations/{org_id}/oauth-clients</code> answers this until the developer turns it on.
Turn on <strong>Let organizations create integrations</strong> on <strong>Tenant → Authentication → Tokens</strong> and choose <strong>Roles integrations may hold</strong>, or send <code>organization_integrations_enabled: true</code> with <code>organization_integration_role_ids</code> to the Environment's auth settings.
organization.integration_audience_missingConflictAn integration was created while the Environment has no default audience. An integration's tokens always name the Environment's <code>m2m_default_audience</code>, so there must be one.
Set the Environment's <strong>Default audience</strong> (<code>m2m_default_audience</code>) to your API's identifier, then create the integration.
organization.integration_limitConflictThe organization already holds as many integrations as an organization may.
Delete an integration the organization no longer uses, then create the new one.
organization.integration_name_takenConflictAnother of the organization's integrations has this name. Names are compared without regard to case.
Choose another name.
plan_limit_exceededConflictThe Account's plan allows no more of this resource. The error's data names the dimension, the limit and how many are in use.
Remove an existing one, or upgrade the plan from the Workspace's Billing page.
Returned object
curl -X POST "https://auth.canopy-io.com/api/v1/organizations/value/oauth-clients" \ -H "X-API-Key: $CANOPY_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "name": "string" }'
{ "data": { "id": "string", "client_id": "string", "name": "string", "is_active": false, "organization_node_id": "string", "created_by_name": "string", "last_token_at": "2026-04-20T12:00:00.000Z", "previous_secret_expires_at": "2026-04-20T12:00:00.000Z", "secret_rotated_at": "2026-04-20T12:00:00.000Z", "version": 0, "created_at": "2026-04-20T12:00:00.000Z", "roles": [ { "id": "string", "identity_id": "string", "oauth_client_id": "string", "application_node_id": "string", "role_id": "string", "role_name": "string", "node_name": "string", "effective_from": "2026-04-20T12:00:00.000Z", "effective_to": "2026-04-20T12:00:00.000Z", "created_at": "2026-04-20T12:00:00.000Z", "updated_at": "2026-04-20T12:00:00.000Z", "version": 0 } ], "connection": { "token_endpoint": "string", "audience": "string", "token_lifetime_seconds": 0 }, "client_secret": "string" } }
Tell us how we can improve this guide.