openapi: '3.0.3'
info:
title: GC AI External API
version: 1.0.0
description: |-
The GC AI External API allows programmatic access to GC AI's chat capabilities. It's designed for integration with workflow automation tools like Zapier, Make, n8n, or custom applications.
## Authentication
All API requests must include an API key in the `Authorization` header:
```
Authorization: gcai_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
```
API keys can be created in the GC AI app under **Settings → API**.
## Multi-turn Conversations
Conversations can span multiple turns: pass the `chat_id` returned by a completion back on your next request to continue the same chat. See [Multi-turn Conversations](/api-reference/concepts/multi-turn).
## Current Limitations
The following is not yet available via API:
- **Interactive clarification**: the model cannot pause to ask the caller a follow-up question; the `askUserQuestions` tool is disabled on the API surface in beta
## Usage
Usage is tracked and viewable in the GC AI app under **Settings → API → View Usage**.
## Support
For API support, contact [support@gc.ai](mailto:support@gc.ai) or reach out to your account representative.
contact:
email: support@gc.ai
servers:
- url: https://app.gc.ai/api/external/v1
description: Production server
tags:
- name: Chat
description: AI chat completion endpoints
- name: Files
description: File upload and management endpoints
- name: Folders
description: Folder management endpoints
- name: Playbooks
description: Playbook review endpoints
- name: Profiles
description: Personal and company profile endpoints
- name: Projects
description: Project management endpoints
- name: Skills
description: Skill library management endpoints
- name: Utility
description: Health check and connectivity endpoints
- name: Usage
description: Usage and credit/billing reporting endpoints
components:
securitySchemes:
ApiKeyAuth:
type: apiKey
in: header
name: Authorization
description: |-
API key for authentication. Format: `gcai_xxxxxxxxx`
Create API keys in the GC AI app under Settings → API.
schemas:
ChatCompletionResponse:
type: object
properties:
job_id:
type: string
format: uuid
description: Async job identifier
kind:
type: string
enum:
- chat/completions
description: Stable job kind for this endpoint
status:
type: string
enum:
- pending
- running
- succeeded
- failed
- canceled
description: Current job status
result:
$ref: '#/components/schemas/ChatCompletionResult'
error:
type: object
nullable: true
properties:
code:
type: string
message:
type: string
required:
- code
- message
description: Failure payload when the job has failed
created_at:
type: string
description: ISO 8601 creation timestamp
completed_at:
type: string
nullable: true
description: ISO 8601 completion timestamp, or null when not terminal
required:
- job_id
- kind
- status
- result
- error
- created_at
- completed_at
ChatCompletionResult:
type: object
nullable: true
properties:
result:
type: string
description: The AI-generated response text
example: |-
When reviewing a software license agreement, key terms to examine include:
1. **License Grant** - Understand the scope of rights granted...
chat_id:
type: string
format: uuid
description: The chat ID. API chats stay out of chat history until you materialize them. Pass this ID to `POST /chat/{id}/materialize` to surface the chat. See [Chat Visibility](/api-reference/concepts/chat-visibility).
documents:
type: array
items:
$ref: '#/components/schemas/ApiDocument'
description: Documents produced during this completion — either edits of an attached file (the document editing tool) or newly generated files (the document or slide generation tools). Present only when at least one document was produced. Each entry exposes a new `file_id` and a signed download URL; edits also reference the preserved original via `original_file_id`.
emails:
type: array
items:
$ref: '#/components/schemas/ApiEmail'
description: Email drafts produced during this completion by the email drafting tool. Present only when at least one email was drafted. Each entry is a structured draft (`to`, `subject`, `body`, …) ready to send via your own mail client or provider.
diagrams:
type: array
items:
$ref: '#/components/schemas/ApiDiagram'
description: Diagrams produced during this completion by the diagram tool. Present only when at least one diagram was produced. Each entry exposes validated Mermaid source (`mermaid`) you can render with any Mermaid-compatible renderer.
required:
- result
- chat_id
description: Completion payload when the job has succeeded
ApiDocument:
type: object
properties:
file_id:
type: string
format: uuid
description: The new uploaded file ID for the produced document. Use it with `POST /chat/completions` `file_ids` to apply further edits to this version. Download via `signed_url` for the finished file.
original_file_id:
type: string
format: uuid
description: The `file_id` the changes were applied to (edits only). The original file is preserved unchanged. Omitted for newly generated documents.
filename:
type: string
description: Filename of the produced document (edits are prefixed with `edited_`).
original_filename:
type: string
description: Filename of the source file the changes were applied to (edits only). Omitted for newly generated documents.
signed_url:
type: string
format: uri
description: Time-limited download URL for the produced document. Valid for 7 days from job completion. Download promptly — the URL is not re-minted, so re-fetching the job after expiry returns the same expired URL.
required:
- file_id
- filename
- signed_url
ApiEmail:
type: object
properties:
to:
type: string
description: Recipient email address(es), comma-separated. May be an empty string when the prompt named no recipient — fill it in before sending.
cc:
type: string
description: CC recipient email address(es), comma-separated.
bcc:
type: string
description: BCC recipient email address(es), comma-separated.
subject:
type: string
description: Email subject line. Always present — inferred from context when the prompt did not specify one.
body:
type: string
description: Email body in markdown.
plaintext_body:
type: string
description: Email body with markdown stripped, for plain-text clients.
required:
- to
- subject
- body
- plaintext_body
ApiDiagram:
type: object
properties:
title:
type: string
description: A short descriptive title for the diagram.
diagram_type:
type: string
description: The semantic type of diagram, e.g. orgChart, dealStructure, workflow, timeline, sequence, entityRelationship, or general.
mermaid:
type: string
description: The diagram source as validated Mermaid syntax. Render it with any Mermaid-compatible renderer.
required:
- title
- diagram_type
- mermaid
Error:
type: object
properties:
error:
type: string
description: Error message
code:
type: string
description: Machine-readable error code present on some errors (e.g. `RATE_LIMITED`, `INSUFFICIENT_CREDITS`, `TRIAL_NOT_STARTED`, `BILLING_NOT_CONFIGURED`). Branch on this rather than the human-readable `error` string.
message:
type: string
description: Additional error details
details:
type: object
additionalProperties:
nullable: true
description: Validation error details (for 400 errors)
required:
- error
ChatCompletionRequest:
type: object
properties:
message:
type: string
minLength: 1
description: The user's message or prompt
example: What are the key terms to look for in a software license agreement?
file_ids:
type: array
items:
type: string
format: uuid
description: Optional uploaded file IDs to attach as context for this completion. Upload files first via `POST /files`.
example:
- 123e4567-e89b-12d3-a456-426614174000
playbook_ids:
type: array
items:
type: string
format: uuid
maxItems: 20
description: |-
Optional playbook IDs to ground the completion in (up to 20). The model uses each playbook's checks and guidance to structure its review of the attached files. Discover playbooks via `GET /playbooks`.
Org-scoped keys can use org-visible and official playbooks.
example:
- f9e8d7c6-b5a4-3210-fedc-ba0987654321
playbook_id:
type: string
description: Deprecated and no longer accepted. Use `playbook_ids` (an array) instead. Requests that include this field are rejected with a 400 so the playbook is never silently dropped.
deprecated: true
skill_ids:
type: array
items:
type: string
format: uuid
description: |-
Optional skill IDs to run on the first turn. Each skill's instructions are injected as context for this completion. Discover skills via `GET /skills`.
Only valid when starting a new chat — omit them when continuing with `chat_id`.
example:
- b2c3d4e5-f6a7-4890-bcde-f12345678901
chat_id:
type: string
format: uuid
description: |-
Optional chat ID to continue an existing conversation, from the `chat_id` of a prior completion. Omit to start a new chat.
Conversation state is held server-side, so send only your new `message` (plus any new `file_ids`) — do **not** re-send prior turns or previously returned documents/emails/diagrams. Only one turn may be in flight per chat at a time. See [Multi-turn Conversations](/api-reference/concepts/multi-turn).
example: a1b2c3d4-e5f6-7890-abcd-ef1234567890
required:
- message
MaterializeChatResponse:
type: object
properties:
id:
type: string
format: uuid
description: The chat ID
title:
type: string
nullable: true
description: The chat title, if generated
chat_url:
type: string
format: uri
description: Deep link to open the chat in the GC AI web UI
materialized_at:
type: string
format: date-time
description: When the chat was materialized
required:
- id
- title
- chat_url
- materialized_at
ChatSearchResponse:
type: object
properties:
chats:
type: array
items:
$ref: '#/components/schemas/ChatSearchResult'
description: Chats matching the query. Title-substring matches first, then semantic (vector) matches in relevance order, de-duplicated and capped at `limit`.
required:
- chats
ChatSearchResult:
type: object
properties:
id:
type: string
format: uuid
description: Unique chat identifier
title:
type: string
nullable: true
description: Chat title, or null if untitled
summary:
type: string
nullable: true
description: AI-generated summary of the chat, if any
updated_at:
type: string
description: ISO 8601 last-update timestamp
required:
- id
- title
- summary
- updated_at
FileResponse:
type: object
properties:
id:
type: string
format: uuid
description: Unique file identifier
name:
type: string
description: Original filename
size:
type: number
description: File size in bytes
content_type:
type: string
description: MIME type of the file
example: application/pdf
status:
type: string
enum:
- extracting
- embedding
- ready
- failed
description: Current processing status of the file
created_at:
type: string
description: ISO 8601 creation timestamp
folder_id:
type: string
nullable: true
format: uuid
description: Folder the file belongs to
extraction_error:
type: string
description: Error message if extraction failed
project_id:
type: string
format: uuid
description: Project the file is linked to, if uploaded with project_id
warning:
type: string
description: Present when the file was uploaded successfully but a secondary operation (e.g. project linking) failed
required:
- id
- name
- size
- content_type
- status
- created_at
FileUploadRequest:
type: object
properties:
file:
type: string
format: binary
description: The file to upload
folder_id:
type: string
format: uuid
description: Target folder ID. Defaults to the user's "My Files" folder. Mutually exclusive with `project_id` and `scope`.
project_id:
type: string
format: uuid
description: Upload the file into a project. The file is placed in the project's upload folder and linked to the project. Mutually exclusive with `folder_id` and `scope`.
scope:
type: string
enum:
- my-files
- organization
description: Upload to the root of a meta-collection ("my-files" or "organization"). Mutually exclusive with `folder_id` and `project_id`. `shared-with-me` is not valid for upload.
example: my-files
required:
- file
FileSearchResponse:
type: object
properties:
files:
type: array
items:
$ref: '#/components/schemas/SearchedFile'
description: Files matching the query, ranked by hybrid (vector + keyword) relevance. At most 100 results.
required:
- files
SearchedFile:
type: object
properties:
id:
type: string
format: uuid
description: Unique file identifier
name:
type: string
description: Original filename
size:
type: number
description: File size in bytes
content_type:
type: string
description: MIME type of the file
status:
type: string
enum:
- extracting
- embedding
- ready
- failed
description: Current processing status
folder_id:
type: string
nullable: true
format: uuid
description: Parent folder ID, or null if the file is at the root
created_at:
type: string
description: ISO 8601 creation timestamp
required:
- id
- name
- size
- content_type
- status
- folder_id
- created_at
UpdateFileRequest:
type: object
properties:
folder_id:
type: string
nullable: true
format: uuid
description: Target folder ID to move the file to. Pass null to move to the root.
required:
- folder_id
InitiateUploadResponse:
type: object
properties:
upload_id:
type: string
format: uuid
description: Opaque identifier for this upload session. Use it in the part and complete requests.
part_size:
type: number
description: Recommended part size in bytes. Split the file into parts no larger than this for reliable transfers.
max_parts:
type: number
description: Maximum number of parts allowed for this session. Part numbers run from 1 to this value.
expires_at:
type: string
description: ISO 8601 timestamp after which the session expires. Upload all parts and call complete before this.
required:
- upload_id
- part_size
- max_parts
- expires_at
InitiateUploadRequest:
type: object
properties:
file_name:
type: string
minLength: 1
maxLength: 255
description: Original filename, including extension.
example: msa-2026.pdf
content_type:
type: string
description: MIME type of the file. When omitted, it is derived from the filename extension.
example: application/pdf
size:
type: integer
minimum: 0
exclusiveMinimum: true
description: Total size of the complete file in bytes. Validated up front against the file-size limit so oversized uploads fail before any parts are sent.
example: 12582912
folder_id:
type: string
format: uuid
description: Target folder ID. Defaults to the user's "My Files" folder. Mutually exclusive with `project_id` and `scope`.
project_id:
type: string
format: uuid
description: Upload the file into a project. The file is placed in the project's upload folder and linked to the project. Mutually exclusive with `folder_id` and `scope`.
scope:
type: string
enum:
- my-files
- organization
description: Upload to the root of a meta-collection ("my-files" or "organization"). Mutually exclusive with `folder_id` and `project_id`. User-scoped keys only.
example: my-files
required:
- file_name
- size
UploadPartResponse:
type: object
properties:
upload_id:
type: string
format: uuid
part_number:
type: number
description: The part just stored.
size:
type: number
description: Bytes received for this part.
required:
- upload_id
- part_number
- size
CompleteUploadRequest:
type: object
properties:
part_count:
type: integer
minimum: 1
maximum: 32
description: The total number of parts you uploaded. Parts must be a contiguous run from 1 to this value; completion fails if any are missing.
example: 3
required:
- part_count
AbortUploadResponse:
type: object
properties:
upload_id:
type: string
format: uuid
aborted:
type: boolean
enum:
- true
required:
- upload_id
- aborted
FolderListResponse:
type: object
properties:
folders:
type: array
items:
$ref: '#/components/schemas/Folder'
pagination:
$ref: '#/components/schemas/Pagination'
required:
- folders
- pagination
Folder:
type: object
properties:
id:
type: string
format: uuid
description: Unique folder identifier
name:
type: string
description: Folder name
description:
type: string
nullable: true
description: Folder description, or null if unset
path:
type: string
description: Path through ancestors visible to the requester. Inaccessible ancestors are skipped, so this may not reflect absolute depth. Use `parent_folder_id` to traverse hierarchy.
example: /My Files/Contracts
parent_folder_id:
type: string
nullable: true
format: uuid
description: Parent folder ID, or null for root
folder_type:
type: string
description: Folder type (custom, my-files, etc.)
created_at:
type: string
description: ISO 8601 creation timestamp
required:
- id
- name
- description
- path
- parent_folder_id
- folder_type
- created_at
Pagination:
type: object
properties:
limit:
type: number
description: Page size
offset:
type: number
description: Current offset
has_more:
type: boolean
description: Whether more results exist
required:
- limit
- offset
- has_more
CreateFolderRequest:
type: object
properties:
name:
type: string
minLength: 2
description: Folder name (min 2 characters)
example: Q4 Contracts
description:
type: string
description: Optional description
parent_folder_id:
type: string
format: uuid
description: Parent folder ID. Mutually exclusive with `scope`. If both are omitted, creates a top-level folder.
scope:
type: string
enum:
- my-files
- organization
description: Create the folder at the root of a meta-collection. Mutually exclusive with `parent_folder_id`. `shared-with-me` is not valid for create.
example: my-files
required:
- name
UpdateFolderRequest:
type: object
properties:
name:
type: string
minLength: 2
description: New folder name (minimum 2 characters)
description:
type: string
description: New folder description
parent_folder_id:
type: string
format: uuid
description: Target parent folder ID. The destination must not be the folder itself or one of its descendants.
is_access_controlled:
type: boolean
description: Whether the folder requires explicit access grants
FolderChildrenResponse:
type: object
properties:
items:
type: array
items:
$ref: '#/components/schemas/FolderChild'
description: Direct children of the folder. Subfolders first (alphabetical), then files (alphabetical).
required:
- items
FolderChild:
oneOf:
- allOf:
- $ref: '#/components/schemas/Folder'
- type: object
properties:
type:
type: string
enum:
- folder
required:
- type
- allOf:
- $ref: '#/components/schemas/File'
- type: object
properties:
type:
type: string
enum:
- file
required:
- type
File:
type: object
properties:
id:
type: string
format: uuid
description: Unique file identifier
name:
type: string
description: Original filename
size:
type: number
description: File size in bytes
content_type:
type: string
description: MIME type of the file
status:
type: string
enum:
- extracting
- embedding
- ready
- failed
description: Current processing status
created_at:
type: string
description: ISO 8601 creation timestamp
required:
- id
- name
- size
- content_type
- status
- created_at
ProjectListResponse:
type: object
properties:
projects:
type: array
items:
$ref: '#/components/schemas/ProjectResponse'
pagination:
$ref: '#/components/schemas/Pagination'
required:
- projects
- pagination
ProjectResponse:
type: object
properties:
id:
type: string
format: uuid
description: Unique project identifier
name:
type: string
description: Project name
description:
type: string
nullable: true
description: Project description, or null if unset
custom_instructions:
type: string
nullable: true
description: Custom instructions injected into chats opened in this project
is_access_controlled:
type: boolean
description: When true, only the creator and explicitly granted users can see the project. When false, any member of the organization can see it.
my_access_level:
type: string
nullable: true
enum:
- read
- write
- admin
- null
description: "Caller's access level on this project: `admin` (creator or explicitly granted admin), `write`, `read`, or `null` if the caller has no recorded grant. `null` is also returned for org-scoped keys, which carry no user identity."
created_at:
type: string
description: ISO 8601 creation timestamp
updated_at:
type: string
description: ISO 8601 last-update timestamp
required:
- id
- name
- description
- custom_instructions
- is_access_controlled
- my_access_level
- created_at
- updated_at
CreateProjectRequest:
type: object
properties:
name:
type: string
minLength: 1
description: Project name (required, non-empty after trim)
example: 'Vendor: Acme MSA'
description:
type: string
nullable: true
description: Optional project description
custom_instructions:
type: string
nullable: true
description: Optional custom instructions for chats in this project
is_access_controlled:
type: boolean
description: When true (default), the project is visible only to the creator and explicitly granted users. When false, any member of the organization can see it.
required:
- name
UpdateProjectRequest:
type: object
properties:
name:
type: string
minLength: 1
description: New project name (non-empty after trim)
example: 'Vendor: Acme MSA (renamed)'
description:
type: string
nullable: true
description: New project description, or null to clear it
custom_instructions:
type: string
nullable: true
description: New custom instructions for chats in this project, or null to clear them
AttachFileRequest:
type: object
properties:
file_id:
type: string
format: uuid
description: ID of an already-uploaded file to attach to the project
required:
- file_id
ProjectFileListResponse:
type: object
properties:
files:
type: array
items:
$ref: '#/components/schemas/ProjectFile'
pagination:
$ref: '#/components/schemas/Pagination'
required:
- files
- pagination
ProjectFile:
type: object
properties:
id:
type: string
format: uuid
description: Unique file identifier
name:
type: string
description: Original filename
size:
type: number
description: File size in bytes
content_type:
type: string
description: MIME type of the file
status:
type: string
enum:
- extracting
- embedding
- ready
- failed
description: Current processing status
folder_id:
type: string
nullable: true
format: uuid
description: Folder the file is stored in, or null
created_at:
type: string
description: ISO 8601 creation timestamp
required:
- id
- name
- size
- content_type
- status
- folder_id
- created_at
ProjectFolderListResponse:
type: object
properties:
folders:
type: array
items:
$ref: '#/components/schemas/ProjectFolder'
pagination:
$ref: '#/components/schemas/Pagination'
required:
- folders
- pagination
ProjectFolder:
type: object
properties:
id:
type: string
format: uuid
description: Unique folder identifier
name:
type: string
description: Folder name
description:
type: string
nullable: true
description: Folder description, or null if unset
folder_type:
type: string
description: Folder type (custom, my-files, etc.)
required:
- id
- name
- description
- folder_type
AttachFolderRequest:
type: object
properties:
folder_id:
type: string
format: uuid
description: ID of the folder to attach. All files in the folder become available as project context.
required:
- folder_id
ProjectChatListResponse:
type: object
properties:
chats:
type: array
items:
$ref: '#/components/schemas/ProjectChat'
pagination:
$ref: '#/components/schemas/Pagination'
required:
- chats
- pagination
ProjectChat:
type: object
properties:
id:
type: string
format: uuid
description: Unique chat identifier
title:
type: string
nullable: true
description: Chat title, or null if untitled
summary:
type: string
nullable: true
description: AI-generated summary of the chat, if any
created_at:
type: string
description: ISO 8601 creation timestamp
updated_at:
type: string
description: ISO 8601 last-update timestamp
required:
- id
- title
- summary
- created_at
- updated_at
PlaybookListResponse:
type: object
properties:
playbooks:
type: array
items:
$ref: '#/components/schemas/PlaybookSummary'
pagination:
$ref: '#/components/schemas/Pagination'
required:
- playbooks
- pagination
PlaybookSummary:
type: object
properties:
id:
type: string
format: uuid
description: Unique playbook identifier
title:
type: string
description: Playbook title
description:
type: string
nullable: true
description: Playbook description, or null if unset
is_official:
type: boolean
description: Whether
# --- truncated at 32 KB (292 KB total) ---
# Full source: https://raw.githubusercontent.com/api-evangelist/gc-ai/refs/heads/main/openapi/gc-ai-openapi-original.yml