The Corpus API allows you to manage a Corpus within a Project in Glob.AI OS.
You can create, get, update, and delete Corpora, upload, list, reindex, and delete their documents, and configure how each corpus ingests and chunks content via the geai Ingestion Provider.
For generic variables needed to use the API, see the API Reference.
All endpoints on this page require project-scoped access to the target Corpus's Organization/Project.
| Method |
Path |
Description |
| GET |
/v1/corpus |
List all the corpora available in the Project |
| POST |
/v1/corpus |
Create a corpus |
| GET |
/v1/corpus/{CorpusId} |
Get a corpus by id |
| PUT |
/v1/corpus/{CorpusId} |
Update a corpus |
| DELETE |
/v1/corpus/{CorpusId} |
Delete a corpus |
| GET |
/v1/corpus/{CorpusId}/resources |
List documents in a corpus (filters + paging) |
| DELETE |
/v1/corpus/{CorpusId}/resources |
Delete all documents (clean the corpus) |
| PUT |
/v1/corpus/{CorpusId}/resources |
Reindex all documents in a corpus |
| POST |
/v1/corpus/{CorpusId}/resource |
Upload a document |
| PUT |
/v1/corpus/{CorpusId}/resource |
Reindex a single document |
| GET |
/v1/corpus/{CorpusId}/resource/{ResourceId} |
Get a single document |
| DELETE |
/v1/corpus/{CorpusId}/resource/{ResourceId} |
Delete a single document |
| GET |
/v1/document/{ResourceId} |
Download a document's extracted content |
All endpoints require authentication using one of the following:
- Authorization: Bearer $GEAI_APITOKEN
- Authorization: Bearer $OAuth_accesstoken
For $OAuth_accesstoken, you must also include the header: ProjectId: $GEAI_PROJECT_ID
Some endpoints may require additional headers such as:
- Content-Type: application/json
- Accept: application/json
List all the corpora available in the Project.
- Method: GET
- Path: $BASE_URL/v1/corpus
- Request Body: Empty
{
"corpus":[
{
"id": "string", // GUID, CorpusId
"name": "string", // corpus display name
"description": "string", // corpus description
"type": "vectorstore" // corpus type, always "vectorstore" for corpora created via this API
}
],
"organizationId": "string", // GUID
"projectId": "string" // GUID
}
curl -X GET "$BASE_URL/v1/corpus" \
-H "Authorization: Bearer $GEAI_APITOKEN" \
-H "project-id: $GEAI_PROJECT_ID"
Create a corpus.
The request body is sent flat (the corpus object directly, no envelope).
- Method: POST
- Path: $BASE_URL/v1/corpus
{
"name": "string", // required, corpus display name
"description": "string", // required, must not contain line breaks or special characters
"status": "string", // optional, e.g. "active"
"config": { // optional, indexing configuration
"embeddings": {
"provider": "string", // e.g. "openai" - embeddings service provider
"modelName": "string", // embeddings model; options depend on provider
"dimensions": 0 // optional, integer - embedding vector size, default depends on model
},
"ingestion": {
"provider": "geai", // ingestion provider - see geai Ingestion Provider
"geaiOptions": {}, // object, required when provider="geai" - full field list in geai Ingestion Provider
},
"index": {
"chunks": {
"chunkSize": 1000, // integer, target chunk size in characters - see "Chunking Parameters" in geai Ingestion Provider
"chunkOverlap": 100 // integer, overlapping characters between consecutive chunks
}
}
}
}
The created corpus, same shape as GET /v1/corpus/{CorpusId}; the top-level id is the new CorpusId.
{
"errors": [
{ "id": 0, "description": "Invalid description. Verify the length and avoid special characters." } // returned when description contains line breaks or special characters
]
}
curl -X POST "$BASE_URL/v1/corpus" \
-H "Authorization: Bearer $GEAI_APITOKEN" \
-H "project-id: $GEAI_PROJECT_ID" \
-H "Content-Type: application/json" \
-d '{
"name": "corpus-name",
"description": "corpus-description",
"config": {
"embeddings": {
"provider": "openai",
"modelName": "text-embedding-3-large",
"dimensions": 1536
},
"ingestion": {
"provider": "geai",
"geaiOptions": { "strategy": "auto" }
},
"index": {
"chunks": { "chunkSize": 1000, "chunkOverlap": 100 }
}
}
}'
Get a corpus by id.
| Name |
Type |
Description |
| CorpusId |
string (uuid), path |
Corpus id |
- Method: GET
- Path: $BASE_URL/v1/corpus/{CorpusId}
- Request Body: Empty
{
"id": "string", // GUID, CorpusId
"name": "string", // corpus display name
"description": "string", // corpus description
"type": "vectorstore", // corpus type
"status": "string", // e.g. "active"
"organizationId": "string", // GUID
"projectId": "string", // GUID
"count": 0, // integer, number of indexed documents
"storage": 0, // integer, total storage used in bytes
"config": {
"embeddings": {
"provider": "string", // embeddings service provider
"modelName": "string", // embeddings model
"dimensions": 0 // integer, embedding vector size
},
"index": {
"chunks": { "chunkSize": 0, "chunkOverlap": 0 } // effective (normalized) chunking config - see geai Ingestion Provider
},
"ingestion": {
"provider": "string", // "geai"
"geaiOptions": {} // effective ingestion options - see geai Ingestion Provider
}
}
}
curl -X GET "$BASE_URL/v1/corpus/{CorpusId}" \
-H "Authorization: Bearer $GEAI_APITOKEN" \
-H "project-id: $GEAI_PROJECT_ID"
Update a corpus.
The request body is sent flat (the corpus object directly, no envelope). The response echoes the resulting corpus with its effective (normalized) configuration.
| Name |
Type |
Description |
| CorpusId |
string (uuid), path |
Corpus id |
- Method: PUT
- Path: $BASE_URL/v1/corpus/{CorpusId}
{
"name": "string", // corpus display name
"description": "string", // corpus description, must not contain line breaks or special characters
"config": {
"embeddings": {
"provider": "string", // embeddings service provider
"modelName": "string", // embeddings model
"dimensions": 0 // integer, embedding vector size
},
"index": {
"chunks": { "chunkSize": 0, "chunkOverlap": 0 } // see "Chunking Parameters" in geai Ingestion Provider
}
}
}
The updated corpus, same shape as GET /v1/corpus/{CorpusId}.
Invalid option combination:
{
"errors": [
{ "id": 2053, "description": "Invalid Chunk Strategy for ParentDocument" } // returned when chunkStrategy is incompatible with useParentDocument=true
]
}
curl -X PUT "$BASE_URL/v1/corpus/{CorpusId}" \
-H "Authorization: Bearer $GEAI_APITOKEN" \
-H "project-id: $GEAI_PROJECT_ID" \
-H "Content-Type: application/json" \
-d '{
"name": "corpus-name",
"description": "corpus-description",
"config": {
"embeddings": { "provider": "openai", "modelName": "text-embedding-3-large", "dimensions": 1536 },
"index": { "chunks": { "chunkSize": 9998, "chunkOverlap": 98 } }
}
}'
Delete a corpus.
| Name |
Type |
Description |
| CorpusId |
string (uuid), path |
Corpus id |
- Method: DELETE
- Path: $BASE_URL/v1/corpus/{CorpusId}
- Request Body: Empty
[
{ "id": 0, "description": "string" } // status/result message
]
curl -X DELETE "$BASE_URL/v1/{CorpusId}" \
-H "Authorization: Bearer $GEAI_APITOKEN" \
-H "project-id: $GEAI_PROJECT_ID"
List documents in a corpus.
| Name |
Type |
Description |
| CorpusId |
string (uuid), path |
Corpus id |
| status |
string, query |
Optional. Filter by index status — exact match. One of success, failed, pending, processing, starting, unknown |
| name |
string, query |
Optional. Filter by document name — partial (like) match |
| extension |
string, query |
Optional. Filter by file extension, e.g. pdf — exact match |
| skip |
integer, query |
Optional. Records to skip (paging) |
| count |
integer, query |
Optional. Max records to return (paging) |
- Method: GET
- Path: $BASE_URL/v1/corpus/{CorpusId}/resources
- Request Body: Empty
{
"organizationId": "string", // GUID
"projectId": "string", // GUID
"corpusId": "string", // GUID
"resources": [
{
"id": "string", // GUID, ResourceId
"name": "string", // document file name
"extension": "string", // file extension, e.g. "pdf"
"timestamp": "2026-07-01T12:03:00Z", // ISO 8601, upload/index timestamp
"url": "string", // document content URL, resolves against the api. host - see GET /v1/document/{ResourceId}
"indexStatus": "success" | "failed" | "pending" | "processing" | "starting" | "unknown",
"size": 0, // integer, bytes
"metadata": [
{ "key": "string", "value": "string" } // arbitrary key/value pair supplied at upload time
]
}
],
"count": 0, // integer, total documents returned
"storage": 0, // integer, total storage used in bytes
"statusCounts": {
"success": 0, "pending": 0, "failed": 0,
"processing": 0, "starting": 0, "unknown": 0 // integer counts per indexStatus value
}
}
curl -X GET "$BASE_URL/v1/corpus/{CorpusId}/resources?count=1&skip=1" \
-H "Authorization: Bearer $GEAI_APITOKEN" \
-H "project-id: $GEAI_PROJECT_ID"
Delete all documents (clean the corpus). Removes every document from the corpus; the corpus itself remains.
| Name |
Type |
Description |
| CorpusId |
string (uuid), path |
Corpus id |
- Method: DELETE
- Path: $BASE_URL/v1/corpus/{CorpusId}/resources
- Request Body: Empty
[
{ "id": 0, "description": "string" } // status/result message
]
curl -X DELETE "$BASE_URL/v1/corpus/{CorpusId}/resources" \
-H "Authorization: Bearer $GEAI_APITOKEN" \
-H "project-id: $GEAI_PROJECT_ID"
Reindex all documents in a corpus. Triggers a full reindex of every document.
| Name |
Type |
Description |
| CorpusId |
string (uuid), path |
Corpus id |
- Method: PUT
- Path: $BASE_URL/v1/corpus/{CorpusId}/resources
- Request Body: Empty
[
{ "id": 0, "description": "Reindex started" } // status/result message
]
curl -X PUT "$BASE_URL/v1/corpus/d3fa8ae4-6837-4c64-a17b-4aa926c4872d/resources" \
-H "Authorization: Bearer $GEAI_APITOKEN" \
-H "project-id: $GEAI_PROJECT_ID" \
-H "Content-Type: application/json" \
-d '{}'
Upload a document into the corpus as multipart/form-data. The document is ingested and indexed synchronously; track progress via the document's indexStatus and via statusCounts on GET /v1/corpus/{CorpusId}/resources.
Per-upload fields (strategy, endPage, password, provider) override the corpus's config.ingestion settings for this document only. For the full set of processing/chunking options behind strategy and provider, see geai Ingestion Provider (provider geai).
| Name |
Type |
Description |
| CorpusId |
string (uuid), path |
Corpus id |
| documentId |
string (uuid), header |
Optional. When set to an existing document id, uploads a new version for / replaces that document instead of creating a new one |
| file |
file, form field |
Required. The document to upload |
| metadata |
string (JSON), form field |
Optional. Arbitrary key/value metadata attached to the document |
| strategy |
string, form field |
Optional. Per-upload ingestion strategy override, e.g. llm, hi_res — see geai Ingestion Provider |
| endPage |
integer, form field |
Optional. Per-upload last page to ingest |
| password |
string, form field |
Optional. Password for a protected PDF |
| provider |
string, form field |
Optional. Per-upload ingestion provider override, e.g. geai |
- Method: POST
- Path: $BASE_URL/v1/corpus/{CorpusId}/resource
- Body: multipart/form-data
The created resource, same shape as GET /v1/corpus/{CorpusId}/resource/{ResourceId}; the top-level id is the new ResourceId.
Whether an explicit per-file Content-Type: application/pdf header is required on the file part, or whether the client's default multipart/form-data boundary handling (e.g. curl -F) is sufficient — verify against the live API before publishing.
curl -X POST "$BASE_URL/v1/corpus/$CORPUS_ID/resource" \
-H "Authorization: Bearer $GEAI_APITOKEN" \
-H "project-id: $GEAI_PROJECT_ID" \
-F "file=@Sample.pdf" \
-F 'metadata={"f1":"filter1","type":"sandbox1","domain":"my domain1","year":2033,"quarter":"q1"}'
Per-upload ingestion overrides (password-protected PDF, LLM strategy, first page only):
curl -X POST "$BASE_URL/v1/corpus/{CorpusId}/resource" \
-H "Authorization: Bearer $GEAI_APITOKEN" \
-H "project-id: $GEAI_PROJECT_ID" \
-F "file=@protected.pdf" \
-F "strategy=llm" \
-F "endPage=1" \
-F "password=1234"
Reindex a single document.
| Name |
Type |
Description |
| CorpusId |
string (uuid), path |
Corpus id |
| resourceId |
string (uuid), header |
Document id to reindex |
- Method: PUT
- Path: $BASE_URL/v1/corpus/{CorpusId}/resource
- Request Body: Empty
[
{ "id": 0, "description": "string" } // status/result message
]
curl -X PUT "$BASE_URL/v1/corpus/{CorpusId}/resource" \
-H "Authorization: Bearer $GEAI_APITOKEN" \
-H "project-id: $GEAI_PROJECT_ID" \
-H "resourceId: $resourceId"
Get a single document.
| Name |
Type |
Description |
| CorpusId |
string (uuid), path |
Corpus id |
| ResourceId |
string (uuid), path |
Document id |
- Method: GET
- Path: $BASE_URL/v1/corpus/{CorpusId}/resource/{ResourceId}
- Request Body: Empty
{
"id": "string", // GUID, ResourceId
"name": "string", // document file name
"extension": "string", // file extension
"keyName": "string", // internal storage key
"timestamp": "2026-07-01T12:03:00Z", // ISO 8601
"url": "string", // document content URL - see GET /v1/document/{ResourceId}
"chunks": "string", // integer as string, number of chunks generated for this document - see geai Ingestion Provider
"indexStatus": "success" | "failed" | "pending" | "processing" | "starting" | "unknown",
"indexDetail": "string", // additional detail, e.g. error info when indexStatus="failed"
"size": 0, // integer, bytes
"metadata": [
{ "key": "string", "value": "string" } // arbitrary key/value pair supplied at upload time
]
}
curl -X GET "$BASE_URL/v1/corpus/{CorpusId}/resource/{ResourceId}" \
-H "Authorization: Bearer $GEAI_APITOKEN" \
-H "project-id: $GEAI_PROJECT_ID"
Delete a single document.
| Name |
Type |
Description |
| CorpusId |
string (uuid), path |
Corpus id |
| ResourceId |
string (uuid), path |
Document id |
- Method: DELETE
- Path: $BASE_URL/v1/corpus/{CorpusId}/resource/{ResourceId}
- Request Body: Empty
[
{ "id": 0, "description": "string" } // status/result message
]
curl -X DELETE "$BASE_URL/v1/corpus/{CorpusId}/resource/{ResourceId}" \
-H "Authorization: Bearer $GEAI_APITOKEN" \
-H "project-id: $GEAI_PROJECT_ID"
Download a document's extracted content. The url field returned for each resource points to this endpoint.
| Name |
Type |
Description |
| ResourceId |
string (uuid), path |
Document id |
- Method: GET
- Path: $BASE_URL/v1/document/{ResourceId}
- Request Body: Empty
Content-Type: text/plain, headers X-Frame-Options: deny and X-Content-Type-Options: nosniff. Body is the document's extracted plain text. Requires a logged-in browser session, or the same Authorization + project-id headers when accessed programmatically.
curl -X GET "$BASE_URL/v1/document/{ResourceId}" \
-H "Authorization: Bearer $GEAI_APITOKEN" \
-H "project-id: $GEAI_PROJECT_ID"
Since version 2026-06.