API & MCP
Datasets API
The datasets endpoints are how an integration discovers what's available and manages dataset metadata. To read a dataset's rows, use the querying endpoints instead. Note the identifier split: these routes take the dataset UUID (:datasetID), while the query routes take the gp_… table name.
There is no create, update, or delete for datasets on this API — ingestion happens in the app or through the create_dataset MCP tool.
List datasets — GET /datasets#
The entry point for discovery. Returns every dataset your key can reach, each paired with its project, so one call maps out projects, datasets and table names together.
curl -H "Authorization: Bearer gp_pub_…" \
"https://<your-gopie-host>/v1/api/datasets?query=orders&limit=20&page=1"| Query param | Default | Meaning |
|---|---|---|
query | — | case-insensitive substring match on name, alias or description |
limit | 10 | page size |
page | 1 | 1-based page number |
{
"results": [
{ "id": "550e8400-…", "name": "gp_DzuutVJef9rSG", "alias": "Orders",
"description": "Line-item order facts", "row_count": 1200,
"project_id": "…", "project_name": "Sales Analytics",
"created_at": "2026-07-04T…", "created_by": "…" }
],
"offset": 0, "limit": 20, "total": 3
}A dataset that lives in more than one project appears once per project. Use name (the gp_… value) with the query endpoints.
Get one dataset — GET /datasets/{datasetID}#
Full metadata for a dataset by its UUID, including its column list:
{
"id": "550e8400-…", "name": "gp_DzuutVJef9rSG", "alias": "Orders",
"description": "Line-item order facts", "row_count": 1200, "size": 1048576,
"columns": [ { "name": "revenue", "type": "DOUBLE" } ],
"source": "file", "custom_prompt": "", "has_dashboard": true,
"created_at": "…", "updated_at": "…", "org_id": "…"
}A view id resolves here too, returning the same shape. GET /datasets/{datasetID}/project returns just { "project_id": "…" } — the hop from a dataset back to its project.
Column descriptions#
Descriptions power better chat and search results, and you can manage them over the API.
GET /datasets/{datasetID}/column-descriptions returns the stored summary with each column's description. PATCH the same path updates them:
curl -X PATCH "https://<your-gopie-host>/v1/api/datasets/550e8400-…/column-descriptions" \
-H "Authorization: Bearer gp_pub_…" \
-H "Content-Type: application/json" \
-d '{"column_descriptions": {"revenue": "Line-item revenue in USD", "region": "Sales region code"}}'Only keys matching real columns are applied; if none match you get a 400. A successful patch also triggers a background reindex so chat picks up the new descriptions. Descriptions survive refreshes — you don't need to re-apply them after new data lands.
Reindex for chat — POST /datasets/{datasetID}/reindex#
Re-runs semantic schema indexing so chat works — useful if a dataset's create-time indexing failed. No file re-upload, no data change.
curl -X POST "https://<your-gopie-host>/v1/api/datasets/550e8400-…/reindex" \
-H "Authorization: Bearer gp_pub_…"The body is optional; pass {"project_id": "…"} to disambiguate a dataset that lives in several projects. A successful call returns { "message": "Dataset re-indexed successfully", "indexed": true }. If the AI service is unreachable you get a 502 with "indexed": false.
Share a dataset#
The :datasetID/users sub-routes mirror the app's Manage access panel — granting an organisation member direct access to one dataset. Only owners and admins can grant, and the target must already be an organisation member (a 403 otherwise).
| Method + path | Body | Effect |
|---|---|---|
GET /datasets/{datasetID}/users | — | list members with a grant (paginated) |
PUT /datasets/{datasetID}/users | {"user_id": "…"} | grant access |
DELETE /datasets/{datasetID}/users | {"user_id": "…"} | revoke access |
NoteThese grants control what people see in the app. They are separate from application grants, which control what API keys reach — see Sharing & access.