Organization Integrations
7 operations.
| Method | Endpoint | Description |
|---|---|---|
| GET | /api/v1/organization-integrations/presets | List BYOC preset catalog |
| GET | /api/v1/organizations/{organizationIdOrSlug}/integrations | List organization integrations |
| POST | /api/v1/organizations/{organizationIdOrSlug}/integrations | Register a BYOC organization integration |
| GET | /api/v1/organizations/{organizationIdOrSlug}/integrations/{integrationId} | Get organization integration |
| PATCH | /api/v1/organizations/{organizationIdOrSlug}/integrations/{integrationId} | Rotate client credentials |
| DELETE | /api/v1/organizations/{organizationIdOrSlug}/integrations/{integrationId} | Remove an organization integration |
| POST | /api/v1/organizations/{organizationIdOrSlug}/integrations/{integrationId}/verify | Verify BYOC OAuth credentials |
List BYOC preset catalog
GET/api/v1/organization-integrations/presets
List the OAuth 2.0 BYOC integration presets supported by this deployment. Each preset carries the principal-binding declaration, documented scopes, admin setup instructions, and the redirect URI that must be registered on the admin's OAuth client.
Static bearer-token presets are intentionally excluded from this OAuth client-registration catalog because they do not require an OAuth client.
The catalog is a curated, code-defined list — only Perstack ships new presets; admins register credentials against an existing preset.
Responses
| Status | Description | Body |
|---|---|---|
| 200 | Response for status 200 | application/json object
|
| 400 | The request is malformed or cannot be processed. | application/json PublicApiError
|
| 401 | Authentication failed. Possible reasons: - Authorization header is not provided - Invalid API key - Session expired | application/json PublicApiError
|
| 403 | Access denied. The authenticated user does not have permission to perform this action. | application/json PublicApiError
|
| 422 | Request validation failed. Check the request body, query parameters, or path parameters. | application/json PublicApiError
|
| 500 | The server could not complete the request. | application/json PublicApiError
|
List organization integrations
GET/api/v1/organizations/{organizationIdOrSlug}/integrations
List BYOC OAuth 2.0 client registrations for the current organization. Only returns metadata — client secrets are never included in the response.
Parameters
path
| Name | Type | Required | Description |
|---|---|---|---|
| organizationIdOrSlug | string | required | Identifies the organization by its stable identifier or slug. Applies to List organization integrations. |
Responses
| Status | Description | Body |
|---|---|---|
| 200 | Response for status 200 | application/json object
|
| 400 | The request is malformed or cannot be processed. | application/json PublicApiError
|
| 401 | Authentication failed. Possible reasons: - Authorization header is not provided - Invalid API key - Session expired | application/json PublicApiError
|
| 403 | Access denied. The authenticated user does not have permission to perform this action. | application/json PublicApiError
|
| 422 | Request validation failed. Check the request body, query parameters, or path parameters. | application/json PublicApiError
|
| 500 | The server could not complete the request. | application/json PublicApiError
|
Register a BYOC organization integration
POST/api/v1/organizations/{organizationIdOrSlug}/integrations
Register the admin-supplied OAuth 2.0 client credentials for a preset.
The credentials are probed against the provider's token endpoint inside
this request — registration is only persisted when the probe succeeds
(invalid_grant response). A definitive rejection of the supplied
config (invalid_client, redirect_uri_mismatch, unexpected response
shape) returns 400 with the diagnostic and writes no row. A transient
upstream outage returns 503, and an upstream rate-limit returns 429
with a Retry-After header — neither writes a row, so the caller can
retry. The persisted row starts active and records successful verification
through verifiedAt.
Subsequent operational drift (rotated credentials, revoked client) is
detected via the manual re-verify endpoint
POST /:integrationId/verify, which updates verifiedAt independently
from lifecycle status and lets ops triage integration-side vs.
connection-side failures.
Only one registration per (organization, presetKey) pair is allowed — re-registering the same preset must go through update or delete + create.
Parameters
path
| Name | Type | Required | Description |
|---|---|---|---|
| organizationIdOrSlug | string | required | Identifies the organization by its stable identifier or slug. Applies to Register a BYOC organization integration. |
Request body
required — Request body for: Register a BYOC organization integration.
application/json
| Name | Type | Required | Description |
|---|---|---|---|
| presetKey | "google-workspace" | required | |
| clientId | string | required | |
| clientSecret | string | required |
Responses
| Status | Description | Body |
|---|---|---|
| 200 | Response for status 200 | application/json object
|
| 400 | Bad Request. Possible reasons: - An integration is already registered for this preset - Verify probe definitively rejected the supplied client credentials (invalid_client, redirect_uri_mismatch, unexpected-provider-response) | application/json PublicApiError
|
| 401 | Authentication failed. Possible reasons: - Authorization header is not provided - Invalid API key - Session expired | application/json PublicApiError
|
| 403 | Access denied. The authenticated user does not have permission to perform this action. | application/json PublicApiError
|
| 404 | Resource not found. | application/json PublicApiError
|
| 422 | Request validation failed. Check the request body, query parameters, or path parameters. | application/json PublicApiError
|
| 429 | The provider rate-limited the verify probe. Retry after the Retry-After interval. | application/json PublicApiError
|
| 500 | The server could not complete the request. | application/json PublicApiError
|
| 503 | The provider was transiently unreachable during the verify probe. Retry with backoff. | application/json PublicApiError
|
Get organization integration
GET/api/v1/organizations/{organizationIdOrSlug}/integrations/{integrationId}
Fetch a single BYOC OAuth 2.0 client registration. Client secret is never returned.
Parameters
path
| Name | Type | Required | Description |
|---|---|---|---|
| organizationIdOrSlug | string | required | Identifies the organization by its stable identifier or slug. Applies to Get organization integration. |
| integrationId | string | required | Identifies the organization integration being addressed. Applies to Get organization integration. |
Responses
| Status | Description | Body |
|---|---|---|
| 200 | Response for status 200 | application/json object
|
| 400 | The request is malformed or cannot be processed. | application/json PublicApiError
|
| 401 | Authentication failed. Possible reasons: - Authorization header is not provided - Invalid API key - Session expired | application/json PublicApiError
|
| 403 | Access denied. The authenticated user does not have permission to perform this action. | application/json PublicApiError
|
| 404 | Resource not found. | application/json PublicApiError
|
| 422 | Request validation failed. Check the request body, query parameters, or path parameters. | application/json PublicApiError
|
| 500 | The server could not complete the request. | application/json PublicApiError
|
Rotate client credentials
PATCH/api/v1/organizations/{organizationIdOrSlug}/integrations/{integrationId}
Rotate the admin-supplied client ID and/or client secret. The new credentials are probed against the provider's token endpoint inside this request — the rotation is only persisted when the probe succeeds. A definitive probe rejection returns 400 with the diagnostic; a transient upstream outage returns 503 and an upstream rate-limit returns 429 with a Retry-After header. In every failure case the existing row is left untouched, so the integration cannot silently degrade into an unusable state.
The preset key is immutable — deleting and re-creating is the only way to switch preset.
Parameters
path
| Name | Type | Required | Description |
|---|---|---|---|
| organizationIdOrSlug | string | required | Identifies the organization by its stable identifier or slug. Applies to Rotate client credentials. |
| integrationId | string | required | Identifies the organization integration being addressed. Applies to Rotate client credentials. |
Request body
required — Request body for: Rotate client credentials.
application/json
| Name | Type | Required | Description |
|---|---|---|---|
| clientId | string | optional | |
| clientSecret | string | optional |
Responses
| Status | Description | Body |
|---|---|---|
| 200 | Response for status 200 | application/json object
|
| 400 | Bad Request | application/json PublicApiError
|
| 401 | Authentication failed. Possible reasons: - Authorization header is not provided - Invalid API key - Session expired | application/json PublicApiError
|
| 403 | Access denied. The authenticated user does not have permission to perform this action. | application/json PublicApiError
|
| 404 | Resource not found. | application/json PublicApiError
|
| 422 | Request validation failed. Check the request body, query parameters, or path parameters. | application/json PublicApiError
|
| 429 | The provider rate-limited the verify probe. Retry after the Retry-After interval. | application/json PublicApiError
|
| 500 | The server could not complete the request. | application/json PublicApiError
|
| 503 | The provider was transiently unreachable during the verify probe. Retry with backoff. | application/json PublicApiError
|
Remove an organization integration
DELETE/api/v1/organizations/{organizationIdOrSlug}/integrations/{integrationId}
Remove an organization's OAuth 2.0 client registration by its integration ID.
Parameters
path
| Name | Type | Required | Description |
|---|---|---|---|
| organizationIdOrSlug | string | required | Identifies the organization by its stable identifier or slug. Applies to Remove an organization integration. |
| integrationId | string | required | Identifies the organization integration being addressed. Applies to Remove an organization integration. |
Responses
| Status | Description | Body |
|---|---|---|
| 204 | Response for status 204 | none |
| 400 | The request is malformed or cannot be processed. | application/json PublicApiError
|
| 401 | Authentication failed. Possible reasons: - Authorization header is not provided - Invalid API key - Session expired | application/json PublicApiError
|
| 403 | Access denied. The authenticated user does not have permission to perform this action. | application/json PublicApiError
|
| 404 | Resource not found. | application/json PublicApiError
|
| 422 | Request validation failed. Check the request body, query parameters, or path parameters. | application/json PublicApiError
|
| 500 | The server could not complete the request. | application/json PublicApiError
|
Verify BYOC OAuth credentials
POST/api/v1/organizations/{organizationIdOrSlug}/integrations/{integrationId}/verify
Probe the provider's token endpoint with the admin-registered credentials and
a deliberately-bogus authorization code. A correctly-configured OAuth client
fails with invalid_grant (credentials valid, code wrong) — that is the
success signal. Any other failure maps to a specific diagnostic the UI can
render.
A definitive verification result (success or a config-level failure) is
persisted to verifiedAt and returned 200 with the outcome in the body.
A transient upstream outage returns 503 / 429 with a Retry-After header
and leaves the stored lifecycle status untouched, so a provider blip can never
poison the integration's verification state.
Parameters
path
| Name | Type | Required | Description |
|---|---|---|---|
| organizationIdOrSlug | string | required | Identifies the organization by its stable identifier or slug. Applies to Verify BYOC OAuth credentials. |
| integrationId | string | required | Identifies the organization integration being addressed. Applies to Verify BYOC OAuth credentials. |
Responses
| Status | Description | Body |
|---|---|---|
| 200 | Response for status 200 | application/json object
|
| 400 | Bad Request | application/json PublicApiError
|
| 401 | Authentication failed. Possible reasons: - Authorization header is not provided - Invalid API key - Session expired | application/json PublicApiError
|
| 403 | Access denied. The authenticated user does not have permission to perform this action. | application/json PublicApiError
|
| 404 | Resource not found. | application/json PublicApiError
|
| 422 | Request validation failed. Check the request body, query parameters, or path parameters. | application/json PublicApiError
|
| 429 | The provider rate-limited the verify probe. Retry after the Retry-After interval. The stored status is left unchanged. | application/json PublicApiError
|
| 500 | The server could not complete the request. | application/json PublicApiError
|
| 503 | The provider was transiently unreachable during the verify probe. Retry with backoff. The stored status is left unchanged. | application/json PublicApiError
|