openapi: 3.2.0 info: title: Pipeshub OAuth Provider API version: 1.0.0 contact: name: API Support email: support@pipeshub.com description: 'Operations tagged OAuth Provider across 2 of this provider''s published API definitions: pipeshub-openapi.yaml, pipeshub-openapi.yml. Each path carries the servers of the definition it was published in.' servers: - url: '{instance_url}/api/v1' description: Base API URL variables: instance_url: default: https://app.pipeshub.com description: Base server URL (without /api/v1) - url: '{instance_url}' description: Root URL (used for MCP endpoints mounted at /mcp) variables: instance_url: default: https://app.pipeshub.com description: Base server URL security: - bearerAuth: [] - oauth2: [] tags: - name: OAuth Provider description: PipesHub OAuth 2.0 Authorization Server implementing RFC 6749, RFC 7636 (PKCE), and OpenID Connect. paths: /oauth2/authorize: get: tags: - OAuth Provider summary: Initiate OAuth authorization flow description: 'OAuth 2.0 Authorization Endpoint (RFC 6749 Section 4.1.1). Initiates the authorization code flow. Users are redirected here by OAuth clients to authorize access to their account. **Flow:** 1. Client redirects user to this endpoint with required parameters 2. If not logged in, user is redirected to PipesHub login 3. User sees consent page with requested scopes 4. User grants or denies consent 5. User is redirected back to client with authorization code **PKCE Support (RFC 7636):** - Required for public clients (SPA, mobile apps), enforced on both this GET and the consent POST - Recommended for confidential clients - Only the S256 method (SHA256 hash of code_verifier) is accepted; `plain` is rejected **Security:** - Always use HTTPS in production - State parameter provides CSRF protection - Redirect URI must match registered URIs exactly' operationId: oauthAuthorize security: [] parameters: - name: response_type in: query required: true schema: type: string enum: - code description: Must be "code" for authorization code grant - name: client_id in: query required: true schema: type: string description: OAuth app client ID - name: redirect_uri in: query required: true schema: type: string format: uri description: Callback URI (must match registered URI) - name: scope in: query required: true schema: type: string description: Space-separated list of requested scopes example: openid profile email read:records - name: state in: query required: true schema: type: string description: Random string for CSRF protection - name: code_challenge in: query required: false schema: type: string description: PKCE code challenge (base64url-encoded) - name: code_challenge_method in: query required: false schema: type: string enum: - S256 description: PKCE method. Only S256 is accepted; defaults to S256 when omitted. - name: nonce in: query required: false schema: type: string description: Nonce for ID token binding responses: '302': description: 'Redirects to either: - Login page (if user not authenticated) - Consent page (if user authenticated) - Redirect URI with code (if consent already granted) - Redirect URI with error (if request invalid) ' headers: Location: schema: type: string description: Redirect URL '400': description: Invalid request parameters content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' post: tags: - OAuth Provider summary: Submit authorization consent description: 'Submit user''s consent decision for OAuth authorization. Called after user reviews the consent page and makes a decision. This endpoint generates an authorization code if consent is granted. **Session only.** The bearer token must be the user''s interactive session JWT. OAuth access tokens and personal access tokens (`phpat_...`) are rejected with `403`, so a client can never consent on the user''s behalf with a token it already holds. **Responses:** - Consent granted: Redirects to client with authorization code - Consent denied: Redirects to client with `access_denied` error' operationId: oauthAuthorizeConsent security: - bearerAuth: [] requestBody: description: Request body for Submit authorization consent content: application/json: schema: $ref: '#/components/schemas/OAuthConsentRequest' required: true responses: '200': description: Consent processed, returns redirect URL with authorization code content: application/json: schema: type: object properties: redirect_uri: type: string format: uri description: URL to redirect user (includes code and state) '400': description: Invalid request content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '401': description: User not authenticated '403': description: 'Bearer token is an OAuth access token or personal access token rather than a user session, or the client is not authorized / the redirect URI is invalid. ' servers: - url: '{instance_url}/api/v1' description: Base API URL variables: instance_url: default: https://app.pipeshub.com description: Base server URL (without /api/v1) - url: '{instance_url}' description: Root URL (used for MCP endpoints mounted at /mcp) variables: instance_url: default: https://app.pipeshub.com description: Base server URL /oauth2/token: post: tags: - OAuth Provider summary: Exchange authorization code for tokens description: 'OAuth 2.0 Token Endpoint (RFC 6749 Section 4.1.3). Exchanges an authorization code, client credentials, or refresh token for access tokens. **Grant Types:** - `authorization_code`: Exchange auth code for tokens (user-based) - `client_credentials`: Get tokens for machine-to-machine auth - `refresh_token`: Get new access token using refresh token For **`client_credentials`**, access tokens represent the **OAuth app creator** (the user who registered the client). The JWT may encode **`userId === client_id`**; the **Node API gateway** resolves the creator (**`createdBy`** claim or OAuth app lookup) — see **OAuth Provider** tag. **Client Authentication:** Can be provided via: - HTTP Basic auth: `Authorization: Basic base64(client_id:client_secret)` - Request body: `client_id` and `client_secret` parameters **PKCE Verification:** If authorization used PKCE, the `code_verifier` must be provided and will be verified against the stored code challenge.' operationId: oauthToken x-pipeshub-sdk: true security: [] requestBody: description: Request payload content: application/x-www-form-urlencoded: schema: $ref: '#/components/schemas/OAuthTokenRequest' application/json: schema: $ref: '#/components/schemas/OAuthTokenRequest' required: true responses: '200': description: Tokens issued successfully content: application/json: schema: $ref: '#/components/schemas/OAuthTokenResponse' example: access_token: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9... token_type: Bearer expires_in: 3600 refresh_token: dGhpcyBpcyBhIHJlZnJlc2ggdG9rZW4... scope: openid profile email id_token: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9... '400': description: Invalid request (missing parameters, invalid code, etc.) content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '401': description: Client authentication failed content: application/json: schema: $ref: '#/components/schemas/OAuthErrorResponse' '429': description: Rate limit exceeded content: application/json: schema: $ref: '#/components/schemas/OAuthClientManagementRateLimitError' servers: - url: '{instance_url}/api/v1' description: Base API URL variables: instance_url: default: https://app.pipeshub.com description: Base server URL (without /api/v1) - url: '{instance_url}' description: Root URL (used for MCP endpoints mounted at /mcp) variables: instance_url: default: https://app.pipeshub.com description: Base server URL /oauth2/revoke: post: tags: - OAuth Provider summary: Revoke an access or refresh token description: 'OAuth 2.0 Token Revocation Endpoint (RFC 7009). Revokes an access token or refresh token, preventing further use. Revoking a refresh token also invalidates associated access tokens. **Use Cases:** - User logs out of third-party app - User revokes app access from account settings - Security incident response **Note:** Returns 200 OK even if token was already revoked or invalid (per RFC 7009, to prevent token enumeration).' operationId: oauthRevoke x-pipeshub-sdk: true security: [] requestBody: description: Request payload content: application/x-www-form-urlencoded: schema: $ref: '#/components/schemas/OAuthRevokeRequest' application/json: schema: $ref: '#/components/schemas/OAuthRevokeRequest' required: true responses: '200': description: Token revoked (or was already invalid) '401': description: Client authentication failed content: application/json: schema: $ref: '#/components/schemas/OAuthErrorResponse' '429': description: Rate limit exceeded content: application/json: schema: $ref: '#/components/schemas/OAuthClientManagementRateLimitError' servers: - url: '{instance_url}/api/v1' description: Base API URL variables: instance_url: default: https://app.pipeshub.com description: Base server URL (without /api/v1) - url: '{instance_url}' description: Root URL (used for MCP endpoints mounted at /mcp) variables: instance_url: default: https://app.pipeshub.com description: Base server URL /oauth2/introspect: post: tags: - OAuth Provider summary: Introspect a token description: 'OAuth 2.0 Token Introspection Endpoint (RFC 7662). Check if a token is active and retrieve its metadata. **Use Cases:** - Resource servers validating tokens - Debugging token issues - Checking token scopes before processing requests **Response:** - Active token: Returns `active: true` with token metadata - Invalid/expired/revoked token: Returns only `active: false`' operationId: oauthIntrospect x-pipeshub-sdk: true security: [] requestBody: description: Request payload content: application/x-www-form-urlencoded: schema: $ref: '#/components/schemas/OAuthIntrospectRequest' application/json: schema: $ref: '#/components/schemas/OAuthIntrospectRequest' required: true responses: '200': description: Token introspection result content: application/json: schema: $ref: '#/components/schemas/OAuthIntrospectResponse' examples: active: summary: Active token value: active: true scope: openid profile email client_id: abc123 username: user@example.com token_type: Bearer exp: 1735686000 iat: 1735682400 user_id: user-id-123 iss: https://api.pipeshub.com inactive: summary: Inactive/invalid token value: active: false '401': description: Client authentication failed content: application/json: schema: $ref: '#/components/schemas/OAuthErrorResponse' '429': description: Rate limit exceeded content: application/json: schema: $ref: '#/components/schemas/OAuthClientManagementRateLimitError' servers: - url: '{instance_url}/api/v1' description: Base API URL variables: instance_url: default: https://app.pipeshub.com description: Base server URL (without /api/v1) - url: '{instance_url}' description: Root URL (used for MCP endpoints mounted at /mcp) variables: instance_url: default: https://app.pipeshub.com description: Base server URL components: schemas: OAuthIntrospectRequest: type: object description: 'OAuth 2.0 Token Introspection Request (RFC 7662). Check if a token is active and get its metadata. ' properties: token: type: string description: The token to introspect token_type_hint: type: string enum: - access_token - refresh_token description: Hint about token type client_id: type: string description: Client ID client_secret: type: string description: Client secret required: - token - client_id OAuthIntrospectResponse: type: object description: 'OAuth 2.0 Token Introspection Response (RFC 7662). Contains token metadata if active, or just `active: false` if not. ' properties: active: type: boolean description: Whether the token is currently active scope: type: string description: Scopes granted to the token client_id: type: string description: Client ID the token was issued to username: type: string description: User identifier (if user-based token) token_type: type: string description: Token type exp: type: integer description: Token expiration timestamp (Unix epoch) iat: type: integer description: Token issuance timestamp (Unix epoch) nbf: type: integer description: Token not-before timestamp (Unix epoch) user_id: type: string description: User ID aud: type: string description: Audience (client ID) iss: type: string description: Issuer URL jti: type: string description: Unique token identifier required: - active OAuthTokenRequest: type: object description: 'OAuth 2.0 Token Request (RFC 6749 Section 4.1.3). Request body for exchanging authorization code or credentials for tokens. ' properties: grant_type: type: string enum: - authorization_code - client_credentials - refresh_token description: 'OAuth grant type: - `authorization_code`: Exchange auth code for tokens - `client_credentials`: Machine-to-machine auth - `refresh_token`: Get new access token using refresh token ' code: type: string description: Authorization code (required for authorization_code grant) redirect_uri: type: string format: uri description: Redirect URI (required for authorization_code grant) client_id: type: string description: Client ID (can also be sent via Basic auth header) client_secret: type: string description: Client secret (can also be sent via Basic auth header) refresh_token: type: string description: Refresh token (required for refresh_token grant) scope: type: string description: Requested scopes (optional, defaults to original grant scopes) code_verifier: type: string description: 'PKCE code verifier (RFC 7636). Required if code_challenge was used. Must be 43-128 characters from [A-Za-z0-9-._~] ' pattern: ^[A-Za-z0-9\-._~]{43,128}$ required: - grant_type OAuthClientManagementRateLimitError: type: object description: JSON body when OAuth client management routes exceed the per-minute rate limit (same limiter as other `/oauth-clients/*` routes). required: - error properties: error: type: object required: - code - message properties: code: type: string example: TOO_MANY_REQUESTS message: type: string example: Too many OAuth client requests. Please try again later. retryAfter: type: - integer - 'null' description: Seconds until the limit window resets (when `Retry-After` is present); may be null. OAuthTokenResponse: type: object description: 'OAuth 2.0 Token Response (RFC 6749 Section 5.1). Contains the access token and optional refresh/ID tokens. ' properties: access_token: type: string description: The access token for API requests token_type: type: string example: Bearer description: Token type (always "Bearer") expires_in: type: integer description: Access token lifetime in seconds example: 3600 refresh_token: type: string description: Refresh token for obtaining new access tokens scope: type: string description: Granted scopes (may differ from requested) id_token: type: string description: OpenID Connect ID token (JWT) if openid scope was requested OAuthErrorResponse: type: object description: 'OAuth 2.0 Error Response (RFC 6749 Section 5.2). Standard error format for OAuth endpoints. ' properties: error: type: string description: 'Error code. Common values: - `invalid_request` - Missing or invalid parameter - `invalid_client` - Client authentication failed - `invalid_grant` - Invalid authorization code or refresh token - `unauthorized_client` - Client not authorized for this grant type - `unsupported_grant_type` - Grant type not supported - `invalid_scope` - Requested scope is invalid or exceeds allowed - `access_denied` - User denied authorization ' enum: - invalid_request - invalid_client - invalid_grant - unauthorized_client - unsupported_grant_type - invalid_scope - access_denied - server_error error_description: type: string description: Human-readable error description error_uri: type: string format: uri description: URI with more information about the error state: type: string description: State parameter from the authorization request required: - error OAuthRevokeRequest: type: object description: 'OAuth 2.0 Token Revocation Request (RFC 7009). Revokes an access or refresh token. ' properties: token: type: string description: The token to revoke token_type_hint: type: string enum: - access_token - refresh_token description: Hint about token type (optional, improves performance) client_id: type: string description: Client ID client_secret: type: string description: Client secret required: - token - client_id OAuthConsentRequest: type: object description: Request to submit user consent for OAuth authorization properties: client_id: type: string description: The OAuth app's client ID redirect_uri: type: string format: uri description: Redirect URI (must match authorization request) scope: type: string description: Requested scopes state: type: string description: State parameter from authorization request consent: type: string enum: - granted - denied description: User's consent decision code_challenge: type: string description: 'PKCE code challenge (base64url, 43-128 chars). Required for public (non-confidential) clients; without it the consent is answered with a redirect carrying `error=invalid_request` and no code is issued. Optional for confidential clients. ' code_challenge_method: type: string enum: - S256 description: PKCE challenge method. Only `S256` is accepted; `plain` is rejected with `400`. Defaults to `S256` when omitted. required: - client_id - redirect_uri - scope - state - consent ErrorResponse: type: object additionalProperties: false description: 'Standard error envelope returned by all errors routed through `ErrorMiddleware`. Applies to all `BaseError` subclasses including `HttpError`, `ValidationError`, and others. The `code` field is a machine-readable string identifying the error type (e.g. `HTTP_UNAUTHORIZED`, `HTTP_NOT_FOUND`, `VALIDATION_ERROR`, `INTERNAL_ERROR`). ' properties: error: type: object additionalProperties: false required: - code - message properties: requestId: type: string description: 'Identifier for this request, echoed so a bug report can quote it. Absent when the request never reached the middleware that assigns one. ' code: type: string description: 'Machine-readable error code. For application errors it takes the form `HTTP_` For unhandled runtime errors (e.g. database unavailable) it is `INTERNAL_ERROR`. ' example: HTTP_BAD_REQUEST message: type: string description: Human-readable description of the error example: Admin access required metadata: type: object description: Additional context (only present in development environments) additionalProperties: true required: - error securitySchemes: bearerAuth: type: http scheme: bearer bearerFormat: JWT description: 'JWT Bearer token for authenticated requests. A personal access token (see the **Personal Access Tokens** tag) is a `phpat_`-prefixed variant of this same JWT — e.g. `phpat_eyJhbGci...`. The prefix is display-only, added for secret-scanner detectability; the gateway strips it before verifying the token, so send it exactly as issued, prefix included. ' scopedToken: type: http scheme: bearer bearerFormat: JWT description: 'Scoped JWT token for service-to-service authentication. Format: "Bearer {scoped_token}" Required scopes vary by endpoint. ' oauth2: type: oauth2 description: 'OAuth 2.0 authentication with fine-grained scopes. Supports authorization_code (with PKCE) and client_credentials flows. OAuth tokens are Bearer JWTs — use the same Authorization header as regular tokens. For **client_credentials**, machine JWTs may use `userId === client_id`; the Node gateway resolves the OAuth app creator — see **OAuth Provider** tag. ' flows: authorizationCode: authorizationUrl: /api/v1/oauth2/authorize tokenUrl: /api/v1/oauth2/token refreshUrl: /api/v1/oauth2/token scopes: openid: OpenID Connect authentication profile: User profile information email: User email address offline_access: Offline access (refresh tokens) org:read: Read organization information org:write: Update organization settings org:admin: Full organization administration user:read: Read user profiles user:write: Update user profiles user:invite: Invite new users user:delete: Delete users usergroup:read: Read user groups usergroup:write: Create and manage user groups team:read: Read team information team:write: Create and manage teams kb:read: Read knowledge bases and records kb:write: Create and update knowledge bases kb:delete: Delete knowledge bases and records kb:upload: Upload files to knowledge bases semantic:read: Read semantic search results and history semantic:write: Execute semantic search semantic:delete: Delete semantic search history conversation:read: Read conversations conversation:write: Create and manage conversations conversation:chat: Send messages in conversations project:read: Read projects and their conversations project:write: Create and manage projects project:delete: Delete projects agent:read: Read AI agents agent:write: Create and manage AI agents agent:execute: Execute AI agents connector:read: Read connector configurations connector:write: Create and update connectors connector:sync: Trigger connector synchronization connector:delete: Delete connectors config:read: Read system configuration config:write: Update system configuration crawl:read: Read crawling jobs crawl:write: Create and manage crawling jobs crawl:delete: Delete crawling jobs clientCredentials: tokenUrl: /api/v1/oauth2/token scopes: openid: OpenID Connect authentication profile: User profile information email: User email address offline_access: Offline access (refresh tokens) org:read: Read organization information org:write: Update organization settings org:admin: Full organization administration user:read: Read user profiles user:write: Update user profiles user:invite: Invite new users user:delete: Delete users usergroup:read: Read user groups usergroup:write: Create and manage user groups team:read: Read team information team:write: Create and manage teams kb:read: Read knowledge bases and records kb:write: Create and update knowledge bases kb:delete: Delete knowledge bases and records kb:upload: Upload files to knowledge bases semantic:write: Execute semantic search semantic:read: Read semantic search results and history semantic:delete: Delete semantic search history conversation:read: Read conversations conversation:write: Create and manage conversations conversation:chat: Send messages in conversations project:read: Read projects and their conversations project:write: Create and manage projects project:delete: Delete projects agent:read: Read AI agents agent:write: Create and manage AI agents agent:execute: Execute AI agents connector:read: Read connector configurations connector:write: Create and update connectors connector:sync: Trigger connector synchronization connector:delete: Delete connectors config:read: Read system configuration config:write: Update system configuration crawl:read: Read crawling jobs crawl:write: Create and manage crawling jobs x-refined-from: - pipeshub-openapi.yaml - pipeshub-openapi.yml