openapi: 3.2.0 info: title: MindCloud Public API Keys API version: 2.0.0 description: REST surface under /v2. Authenticate with a company-scoped API key sent as a bearer token. Each key holds a set of permissions; each operation lists the ones it requires as the apiKey security roles. A request may use a permission only while the user who created the key also holds it. servers: - url: https://connect.mindcloud.co security: - apiKey: [] tags: - name: API Keys paths: /v2/api-keys: get: operationId: v2-list-api-keys summary: 'List API keys for the company: name, last use, and revocation state' description: 'List API keys for the company: name, last use, and revocation state. Key material is never included. Each filterable field is also a query parameter: `status=active` matches it exactly, and bracket operators (eq, ne, gt, gte, lt, lte, contains, starts, ends, in, nin) compare, e.g. `createdOn[gte]=2026-01-01` or `status[in]=failed,cancelled`. contains, starts, and ends apply to text fields only. Requires the API key permission api_key:manage.' tags: - API Keys security: - apiKey: - api_key:manage parameters: - name: fields in: query required: false schema: type: string description: 'Comma-separated fields to return; all of them when left out, and id always. Each item then carries only those keys, whatever its schema requires. Fields: id, name, accessLevel, permissions, usedOn, revokedOn, createdOn, createdBy, updatedOn.' - $ref: '#/components/parameters/limit' - $ref: '#/components/parameters/offset' - name: sort in: query required: false schema: type: string description: 'Comma-separated sort fields; prefix one with - for descending. Sortable fields: id, name, accessLevel, usedOn, revokedOn, createdOn, createdBy, updatedOn. Default: -createdOn.' - name: where in: query required: false schema: type: string maxLength: 2048 description: 'RSQL filter expression. Filterable fields: id, name, accessLevel, usedOn, revokedOn, createdOn, createdBy, updatedOn. Operators: ==, !=, >, >=, <, <=, =in=, =out=, =like=. Logical: ; (AND), , (OR); AND binds tighter than OR. Example: "status==active;name=like=Sales*"' - name: id in: query required: false schema: type: string description: 'Filter on id: `id=value` matches it exactly. Bracket operators: `id[ne]`, `id[gt]`, `id[gte]`, `id[lt]`, `id[lte]`, `id[contains]`, `id[starts]`, `id[ends]`, and `id[in]` / `id[nin]` with comma-separated values.' - name: name in: query required: false schema: type: string description: 'Filter on name: `name=value` matches it exactly. Bracket operators: `name[ne]`, `name[gt]`, `name[gte]`, `name[lt]`, `name[lte]`, `name[contains]`, `name[starts]`, `name[ends]`, and `name[in]` / `name[nin]` with comma-separated values.' - name: accessLevel in: query required: false schema: type: string enum: - read_only - run_workflows - full_access - none description: 'Filter on accessLevel: `accessLevel=value` matches it exactly. Bracket operators: `accessLevel[ne]`, `accessLevel[gt]`, `accessLevel[gte]`, `accessLevel[lt]`, `accessLevel[lte]`, `accessLevel[contains]`, `accessLevel[starts]`, `accessLevel[ends]`, and `accessLevel[in]` / `accessLevel[nin]` with comma-separated values.' - name: usedOn in: query required: false schema: type: string description: 'Filter on usedOn: `usedOn=value` matches it exactly. A date or timestamp, such as 2026-10-01 or 2026-10-01T12:00:00Z. Bracket operators: `usedOn[ne]`, `usedOn[gt]`, `usedOn[gte]`, `usedOn[lt]`, `usedOn[lte]`, and `usedOn[in]` / `usedOn[nin]` with comma-separated values.' - name: revokedOn in: query required: false schema: type: string description: 'Filter on revokedOn: `revokedOn=value` matches it exactly. A date or timestamp, such as 2026-10-01 or 2026-10-01T12:00:00Z. Bracket operators: `revokedOn[ne]`, `revokedOn[gt]`, `revokedOn[gte]`, `revokedOn[lt]`, `revokedOn[lte]`, and `revokedOn[in]` / `revokedOn[nin]` with comma-separated values.' - name: createdOn in: query required: false schema: type: string description: 'Filter on createdOn: `createdOn=value` matches it exactly. A date or timestamp, such as 2026-10-01 or 2026-10-01T12:00:00Z. Bracket operators: `createdOn[ne]`, `createdOn[gt]`, `createdOn[gte]`, `createdOn[lt]`, `createdOn[lte]`, and `createdOn[in]` / `createdOn[nin]` with comma-separated values.' - name: createdBy in: query required: false schema: type: string description: 'Filter on createdBy: `createdBy=value` matches it exactly. Bracket operators: `createdBy[ne]`, `createdBy[gt]`, `createdBy[gte]`, `createdBy[lt]`, `createdBy[lte]`, `createdBy[contains]`, `createdBy[starts]`, `createdBy[ends]`, and `createdBy[in]` / `createdBy[nin]` with comma-separated values.' - name: updatedOn in: query required: false schema: type: string description: 'Filter on updatedOn: `updatedOn=value` matches it exactly. A date or timestamp, such as 2026-10-01 or 2026-10-01T12:00:00Z. Bracket operators: `updatedOn[ne]`, `updatedOn[gt]`, `updatedOn[gte]`, `updatedOn[lt]`, `updatedOn[lte]`, and `updatedOn[in]` / `updatedOn[nin]` with comma-separated values.' responses: '200': description: Success. content: application/json: schema: type: object properties: success: type: boolean const: true data: type: array items: $ref: '#/components/schemas/ApiKeySummary' meta: $ref: '#/components/schemas/ListMeta' required: - success - data - meta default: description: Error. content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' post: operationId: v2-create-api-key summary: Create an API key for the company with an explicit set of permissions, all… description: 'Create an API key for the company with an explicit set of permissions, all within the calling key''s own. The key material is returned once, in this response, and can never be retrieved again. Requires the API key permission api_key:manage.' tags: - API Keys security: - apiKey: - api_key:manage parameters: [] requestBody: required: true content: application/json: schema: type: object properties: name: type: string minLength: 1 maxLength: 256 permissions: maxItems: 27 type: array items: type: string enum: - workflow:view - workflow:create - workflow:edit - workflow:delete - workflow:run - log:view - credential:view - credential:edit - credential:delete - universal:read - universal:create - universal:update - universal:delete - member:view - member:create - member:edit - member:delete - member:owner_edit - role:manage - company:view - company:edit - subscription:view - api_key:manage - embedded:view - embedded:create - child_company:access - child_company:manage accessLevel: type: string enum: - read_only - run_workflows - full_access required: - name responses: '201': description: Success. content: application/json: schema: type: object properties: success: type: boolean const: true data: $ref: '#/components/schemas/ApiKey' meta: type: object description: 'Response metadata, on endpoints that answer it: the usage window, a step count, or the provider paging of a Universal action run.' required: - success - data '400': description: The request body is invalid (INVALID_QUERY), or it sends both permissions and accessLevel (API_KEY_PERMISSIONS_CONFLICT). content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '403': description: The calling key lacks api_key:manage (API_KEY_PERMISSION_DENIED), or the new key would hold a permission the calling key cannot use (API_KEY_PERMISSION_EXCEEDS_ACTOR). content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' default: description: Error. content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' /v2/api-keys/{apiKeyId}: delete: operationId: v2-revoke-api-key summary: Revoke an API key description: 'Revoke an API key. The key stops working immediately. Revoking an already revoked key changes nothing and succeeds. Requires the API key permission api_key:manage.' tags: - API Keys security: - apiKey: - api_key:manage parameters: - name: apiKeyId in: path required: true schema: type: string minLength: 1 responses: '200': description: Success. content: application/json: schema: type: object properties: success: type: boolean const: true data: $ref: '#/components/schemas/DeletedResource' meta: type: object description: 'Response metadata, on endpoints that answer it: the usage window, a step count, or the provider paging of a Universal action run.' required: - success - data default: description: Error. content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' components: parameters: offset: name: offset in: query required: false schema: type: integer minimum: 0 default: 0 description: Number of results to skip for pagination (default 0). limit: name: limit in: query required: false schema: type: integer minimum: 1 maximum: 1000 default: 100 description: Maximum number of results to return (1-1000, default 100). schemas: ErrorResponse: type: object properties: success: type: boolean const: false error: type: object properties: code: type: string description: 'Fixed by the status: 400 VALIDATION_FAILED, 401 UNAUTHORIZED, 403 FORBIDDEN, 404 NOT_FOUND, 409 CONFLICT, 410 GONE, 413 PAYLOAD_TOO_LARGE, 421 and 503 UNAVAILABLE, 429 RATE_LIMITED, 500 INTERNAL_ERROR, 502 PROVIDER_ERROR.' examples: - VALIDATION_FAILED - UNAUTHORIZED - FORBIDDEN - NOT_FOUND - CONFLICT - GONE - PAYLOAD_TOO_LARGE - RATE_LIMITED - INTERNAL_ERROR - PROVIDER_ERROR - UNAVAILABLE message: type: string details: type: object description: The specific cause (reason) and any evidence for it. Absent when the code says everything. properties: reason: type: string description: The specific cause, for example UNKNOWN_FILTER_FIELD or CONNECTION_IN_USE. field: type: string description: The parameter, filter, sort, or body field a 400 refused. accepted: type: array items: {} description: 'What a 400 would have accepted instead: parameter names, field names, or enum values.' provider: type: object description: 'On 502 PROVIDER_ERROR: the provider answer that failed.' properties: status: type: integer description: The provider's HTTP status. code: type: string description: The provider's own error code, when it sends one. required: - code - message required: - success - error ApiKey: type: object properties: id: type: - string - 'null' description: Unique id of the key. name: type: - string - 'null' description: The name the key was created with. accessLevel: type: - string - 'null' enum: - read_only - run_workflows - full_access - none - null description: 'A summary of the key permissions: full_access, run_workflows, read_only, or none. Derived from permissions; it is never set directly.' permissions: type: array items: type: string description: The permissions the key holds. A request may use one only while the key's creator also holds it. key: type: string description: The key itself. It appears only in this response; MindCloud keeps only a hash. createdOn: type: - string - 'null' format: date-time description: When the key was created. required: - id - name - accessLevel - permissions - key - createdOn ListMeta: type: object properties: pagination: type: object properties: totalCount: type: integer description: Matching records. A list read in SQL stops counting at 10000. totalCountExact: type: boolean description: False when totalCount stopped at that cap. hasNextPage: type: boolean description: True when another page follows. Page with this, not totalCount. hasPreviousPage: type: boolean required: - totalCount - totalCountExact - hasNextPage - hasPreviousPage required: - pagination DeletedResource: type: object properties: id: type: string description: The id of the resource that was deleted. required: - id ApiKeySummary: type: object properties: id: type: - string - 'null' description: Unique id of the key. name: type: - string - 'null' description: The name the key was created with. accessLevel: type: - string - 'null' enum: - read_only - run_workflows - full_access - none - null description: 'A summary of the key permissions: full_access, run_workflows, read_only, or none. Derived from permissions; it is never set directly.' permissions: type: array items: type: string description: The permissions the key holds. A request may use one only while the key's creator also holds it. usedOn: type: - string - 'null' format: date-time description: The last time the key was used. Old dates are rotation candidates. revokedOn: type: - string - 'null' format: date-time description: When the key was revoked. Empty while it is active. createdOn: type: - string - 'null' format: date-time description: When the key was created. createdBy: type: - string - 'null' description: Who created it. updatedOn: type: - string - 'null' format: date-time description: When it was last changed. required: - id - name - accessLevel - permissions - usedOn - revokedOn - createdOn - createdBy - updatedOn securitySchemes: apiKey: type: http scheme: bearer description: 'Company-scoped MindCloud API key sent as `Authorization: Bearer `. Each key holds permissions from the MindCloud roles catalog (workflow:view, workflow:run, universal:read, api_key:manage, ...), chosen when it is created; each operation lists the ones it requires as this scheme''s roles. A request may use a permission only while the user who created the key still holds it in the company the request acts on; a missing one answers 403 with details.reason API_KEY_PERMISSION_DENIED and details.required, and a key whose creator left the organization answers API_KEY_CREATOR_INACTIVE. The key''s accessLevel (full_access, run_workflows, read_only, or none) summarizes its permissions. Create a key at https://app.mindcloud.co/user/api-keys.'