Appearance
Databases (extracted tables)
The Databases tab of Apps: tables whose rows are extracted from documents by the data-extractor service (one row per source document), grouped into table databases. Requests are proxied to the extractor service; the API adds authentication and ownership checks.
Endpoints
GET /microservices/data-extractor/tables
List my tables
Tables owned by the caller (scoped by the account's email). No trailing slash on this path.
Auth: Session token · In the app: Apps → Databases; Table builder gallery
Query parameters
| Field | Type | Required | Description |
|---|---|---|---|
organization_name | string | no |
Response 200 — Tables (service response).
| Field | Type | Description |
|---|---|---|
count | integer | Number of tables returned. |
tables | object[] | |
tables[].table_id | string | |
tables[].table_name | string | |
tables[].email | string | Owner (account email). |
tables[].organization_name | string | |
tables[].columns | object[] | |
tables[].columns[].name | string | Column key (also the key of each row's data). Metacharacters are stripped. |
tables[].columns[].instruction | string | What the extractor should pull from each document into this column. |
tables[].columns[].output_type | string ("string", "number", "list", "boolean", "object", "reference") | Default: "string". |
tables[].rows | object[] | |
tables[].rows[].source_uid | string | Identity of the source (document uid or text input). Rows sharing a uid are addressed together. |
tables[].rows[].data | object | Cell values keyed by column name. |
tables[].rows[].filename | string | |
tables[].rows[].created_at | string (date-time) | |
tables[].rows[].updated_at | string (date-time) | |
tables[].rows[].processed_at | string (date-time), nullable | |
tables[].metadata | object | Free-form (e.g. column_widths). |
tables[].created_at | string (date-time) | |
tables[].updated_at | string (date-time) |
Response 403 — The account has no email address.
Response 503 — Extractor service not configured.
Example
bash
curl -X GET "https://api.example.com/microservices/data-extractor/tables" \
-H "Authorization: Token $FINBLADE_TOKEN"GET /microservices/data-extractor/table
Fetch several tables
Auth: Session token
Query parameters
| Field | Type | Required | Description |
|---|---|---|---|
ids | string | yes | Comma-separated table ids. All must be yours or shared with you. |
Response 200 — Tables.
| Field | Type | Description |
|---|---|---|
count | integer | |
tables | object[] | |
tables[].table_id | string | |
tables[].table_name | string | |
tables[].email | string | Owner (account email). |
tables[].organization_name | string | |
tables[].columns | object[] | |
tables[].columns[].name | string | Column key (also the key of each row's data). Metacharacters are stripped. |
tables[].columns[].instruction | string | What the extractor should pull from each document into this column. |
tables[].columns[].output_type | string ("string", "number", "list", "boolean", "object", "reference") | Default: "string". |
tables[].rows | object[] | |
tables[].rows[].source_uid | string | Identity of the source (document uid or text input). Rows sharing a uid are addressed together. |
tables[].rows[].data | object | Cell values keyed by column name. |
tables[].rows[].filename | string | |
tables[].rows[].created_at | string (date-time) | |
tables[].rows[].updated_at | string (date-time) | |
tables[].rows[].processed_at | string (date-time), nullable | |
tables[].metadata | object | Free-form (e.g. column_widths). |
tables[].created_at | string (date-time) | |
tables[].updated_at | string (date-time) |
Response 400 — ids missing.
Response 403 — One of the tables is not accessible.
Example
bash
curl -X GET "https://api.example.com/microservices/data-extractor/table?ids=tbl_9f8e7d6c%2Ctbl_1a2b3c4d" \
-H "Authorization: Token $FINBLADE_TOKEN"POST /microservices/data-extractor/create_table
Create a table
Defines the schema (and optionally seed rows). The owner and organisation are taken from the session. Column names are sanitised.
Auth: Session token · In the app: Table builder → Save table (new)
Request body (application/json)
| Field | Type | Required | Description |
|---|---|---|---|
table_name | string | yes | |
columns | object[] | yes | |
columns[].name | string | yes | Column key (also the key of each row's data). Metacharacters are stripped. |
columns[].instruction | string | no | What the extractor should pull from each document into this column. |
columns[].output_type | string ("string", "number", "list", "boolean", "object", "reference") | no | Default: "string". |
rows | object[] | no | |
rows[].source_uid | string | no | Identity of the source (document uid or text input). Rows sharing a uid are addressed together. |
rows[].data | object | no | Cell values keyed by column name. |
rows[].filename | string | no | |
rows[].created_at | string (date-time) | no | |
rows[].updated_at | string (date-time) | no | |
rows[].processed_at | string (date-time), nullable | no | |
metadata | object | no | |
workflow_id | string | no | Records which workflow created the table (for cascade deletes). |
json
{
"table_name": "Supplier invoices",
"columns": [
{
"name": "supplier",
"instruction": "The supplier's legal name.",
"output_type": "string"
},
{
"name": "invoice_total",
"instruction": "Total payable as a number.",
"output_type": "number"
}
]
}Response 200 — Created (service response; includes table_id).
| Field | Type | Description |
|---|---|---|
table_id | string |
Response 502 — Extractor service error.
Example
bash
curl -X POST "https://api.example.com/microservices/data-extractor/create_table" \
-H "Authorization: Token $FINBLADE_TOKEN" \
-H "Content-Type: application/json" \
-d '{"table_name":"Supplier invoices","columns":[{"name":"supplier","instruction":"The supplier's legal name.","output_type":"string"},{"name":"invoice_total","instruction":"Total payable as a number.","output_type":"number"}]}'PUT /microservices/data-extractor/update_table/{table_id}
Update a table's schema
Partial update of table_name, columns (full array replaces the schema) and metadata (merged). rows are ignored unless the body also carries replace_rows: true, in which case the array replaces every stored row ([] clears the table). Use the row endpoints for single-cell edits and row deletes. Requires write access (owner or editor grant).
Auth: Session token · In the app: Table builder → Save table; column resize
Path parameters
| Field | Type | Required | Description |
|---|---|---|---|
table_id | string | yes |
Request body (application/json)
| Field | Type | Required | Description |
|---|---|---|---|
table_name | string | no | |
columns | object[] | no | |
columns[].name | string | yes | Column key (also the key of each row's data). Metacharacters are stripped. |
columns[].instruction | string | no | What the extractor should pull from each document into this column. |
columns[].output_type | string ("string", "number", "list", "boolean", "object", "reference") | no | Default: "string". |
metadata | object | no | |
rows | object[] | no | |
rows[].source_uid | string | no | Identity of the source (document uid or text input). Rows sharing a uid are addressed together. |
rows[].data | object | no | Cell values keyed by column name. |
rows[].filename | string | no | |
rows[].created_at | string (date-time) | no | |
rows[].updated_at | string (date-time) | no | |
rows[].processed_at | string (date-time), nullable | no | |
replace_rows | boolean | no | Default: false. |
Response 200 — Result.
| Field | Type | Description |
|---|---|---|
table_id | string | |
existing_rows | integer | |
columns_added | string[] | |
columns_removed | string[] | |
warning | string |
Response 403 — Read-only or no access.
Example
bash
curl -X PUT "https://api.example.com/microservices/data-extractor/update_table/tbl_9f8e7d6c" \
-H "Authorization: Token $FINBLADE_TOKEN"GET /microservices/data-extractor/table/{table_id}
Get a table
Auth: Session token · In the app: Apps → Databases → open table
Path parameters
| Field | Type | Required | Description |
|---|---|---|---|
table_id | string | yes |
Response 200 — The table with its rows.
| Field | Type | Description |
|---|---|---|
table_id | string | |
table_name | string | |
email | string | Owner (account email). |
organization_name | string | |
columns | object[] | |
columns[].name | string | Column key (also the key of each row's data). Metacharacters are stripped. |
columns[].instruction | string | What the extractor should pull from each document into this column. |
columns[].output_type | string ("string", "number", "list", "boolean", "object", "reference") | Default: "string". |
rows | object[] | |
rows[].source_uid | string | Identity of the source (document uid or text input). Rows sharing a uid are addressed together. |
rows[].data | object | Cell values keyed by column name. |
rows[].filename | string | |
rows[].created_at | string (date-time) | |
rows[].updated_at | string (date-time) | |
rows[].processed_at | string (date-time), nullable | |
metadata | object | Free-form (e.g. column_widths). |
created_at | string (date-time) | |
updated_at | string (date-time) |
json
{
"table_id": "tbl_9f8e7d6c",
"table_name": "Supplier invoices",
"email": "jane@acme.com",
"organization_name": "Acme",
"columns": [
{
"name": "supplier",
"instruction": "The supplier's legal name.",
"output_type": "string"
},
{
"name": "invoice_total",
"instruction": "Total payable as a number.",
"output_type": "number"
}
],
"rows": [
{
"source_uid": "1b6c1c1e-9d0a-4b6e-9f2a-3c4d5e6f7a8b",
"filename": "invoice-1042.pdf",
"data": {
"supplier": "Globex",
"invoice_total": 1250.5
}
}
],
"metadata": {
"column_widths": {
"supplier": 220
}
},
"created_at": "2026-09-01T09:00:00Z",
"updated_at": "2026-09-22T08:05:41Z"
}Response 403 — Not yours / not shared with you.
Response 404 — Unknown table.
Example
bash
curl -X GET "https://api.example.com/microservices/data-extractor/table/tbl_9f8e7d6c" \
-H "Authorization: Token $FINBLADE_TOKEN"DELETE /microservices/data-extractor/table/{table_id}
Delete a table
Owner only.
Auth: Session token
Path parameters
| Field | Type | Required | Description |
|---|---|---|---|
table_id | string | yes |
Response 200 — Deleted (service response).
Example
bash
curl -X DELETE "https://api.example.com/microservices/data-extractor/table/<table_id>" \
-H "Authorization: Token $FINBLADE_TOKEN"PATCH /microservices/data-extractor/table/{table_id}/rows/{source_uid}
Edit cells of one row
Values are coerced to the column's output_type; machine-managed columns (processed_at, created_at, updated_at, filename) are refused; the edited cell's evidence highlight is dropped. All rows sharing the source_uid are affected.
Auth: Session token · In the app: Table cell edit; evidence viewer field edit
Path parameters
| Field | Type | Required | Description |
|---|---|---|---|
table_id | string | yes | |
source_uid | string | yes |
Request body (application/json)
| Field | Type | Required | Description |
|---|---|---|---|
data | object | yes | Column → new value. |
json
{
"data": {
"invoice_total": 1260
}
}Response 200 — Updated row (service response).
Response 403 — No write access.
Example
bash
curl -X PATCH "https://api.example.com/microservices/data-extractor/table/<table_id>/rows/<source_uid>" \
-H "Authorization: Token $FINBLADE_TOKEN" \
-H "Content-Type: application/json" \
-d '{"data":{"invoice_total":1260}}'DELETE /microservices/data-extractor/table/{table_id}/rows/{source_uid}
Delete a row
Auth: Session token
Path parameters
| Field | Type | Required | Description |
|---|---|---|---|
table_id | string | yes | |
source_uid | string | yes |
Response 200 — Deleted (service response).
Example
bash
curl -X DELETE "https://api.example.com/microservices/data-extractor/table/<table_id>/rows/<source_uid>" \
-H "Authorization: Token $FINBLADE_TOKEN"GET /microservices/data-extractor/table/{table_id}/export
Export a table to Excel
Writes the table to an .xlsx in your media storage and returns where it is — not the file itself. Download it from saved_path with a signed URL, as the app does.
Citation links. Reference cells link to the source PDFs. Inside the app those links are signed as you click them; in an exported file they would expire within the hour. With permanent_links=1 every such link is rewritten into a permanent link so it keeps opening after the file is shared.
Permanent links are public: anyone holding the file can open the linked PDFs without signing in, including people outside your organisation if it is forwarded. Only files you own are linked (refused counts the rest); links are reused across re-exports of the same table and stay revocable from My Data → Artifacts → Links, and die with the file. Signing is best effort — the export succeeds even when some links cannot be made.
Auth: Session token · In the app: Apps → Databases → Export to Excel
Path parameters
| Field | Type | Required | Description |
|---|---|---|---|
table_id | string | yes |
Query parameters
| Field | Type | Required | Description |
|---|---|---|---|
permanent_links | boolean | no | Rewrite citation links into permanent public links. Accepts 1, true or yes. Default: false. |
Response 200 — Exported.
| Field | Type | Description |
|---|---|---|
saved_path | string | Media path of the workbook. |
filename | string | |
permanent_links | object | Present only when permanent_links was requested. |
permanent_links.cells | integer | Cells that contained a citation link. |
permanent_links.signed | integer | Links rewritten to permanent links. |
permanent_links.refused | integer | Links left as they were — typically files you don't own. |
json
{
"saved_path": "Acme/pdf_extracted/jane/invoices_2026-09-25.xlsx",
"filename": "invoices_2026-09-25.xlsx",
"permanent_links": {
"cells": 214,
"signed": 212,
"refused": 2
}
}Response 404 — Not your table.
Response 503 — Extractor service not configured.
Example
bash
curl "https://api.example.com/microservices/data-extractor/table/tbl_9f8e7d6c/export?permanent_links=1" -H "Authorization: Token $FINBLADE_TOKEN"GET /microservices/data-extractor/table/{table_id}/highlights
Evidence highlights for extracted values
Where in the source document each value came from: per field, the verbatim quote and rectangles to draw over the rendered PDF (rect is [x0, y0, x1, y1] as fractions of the page from the top-left; page is 1-based). Empty lists are normal (older extractions, text inputs, non-PDF sources).
Auth: Session token · In the app: Evidence viewer
Path parameters
| Field | Type | Required | Description |
|---|---|---|---|
table_id | string | yes |
Query parameters
| Field | Type | Required | Description |
|---|---|---|---|
source_uid | string | no | Limit to one source document. |
column_name | string | no | Limit to one field. |
Response 200 — Highlights.
| Field | Type | Description |
|---|---|---|
success | boolean | |
result | object | |
result.table_id | string | |
result.source_uid | string | |
result.filename | string | |
result.file_path | string | |
result.file_url | string | |
result.highlights | object[] | |
result.highlights[].column_name | string | |
result.highlights[].value | any | |
result.highlights[].quote | string | |
result.highlights[].status | string ("anchored", "unanchored", "no_evidence") | |
result.highlights[].spans | object[] | |
result.highlights[].spans[].page | integer | |
result.highlights[].spans[].rect | number[] | |
result.highlights[].page_width | number | |
result.highlights[].page_height | number | |
result.highlights[].score | number | |
result.highlights[].ambiguous | boolean |
json
{
"success": true,
"result": {
"table_id": "tbl_9f8e7d6c",
"source_uid": "1b6c1c1e-9d0a-4b6e-9f2a-3c4d5e6f7a8b",
"filename": "invoice-1042.pdf",
"file_path": "/media/Acme/semantic-search/jane/invoice-1042.pdf",
"file_url": "https://api.example.com/media/Acme/semantic-search/jane/invoice-1042.pdf",
"highlights": [
{
"column_name": "invoice_total",
"value": 1250.5,
"quote": "Total due: 1,250.50 SAR",
"status": "anchored",
"spans": [
{
"page": 1,
"rect": [
0.62,
0.71,
0.88,
0.73
]
}
],
"page_width": 612,
"page_height": 792,
"score": 0.98,
"ambiguous": false
}
]
}
}Response 403 — Not your table.
Example
bash
curl -X GET "https://api.example.com/microservices/data-extractor/table/<table_id>/highlights" \
-H "Authorization: Token $FINBLADE_TOKEN"POST /microservices/data-extractor/chat
Chat with a table (extractor service)
Direct question-answering over one table by the extractor service (streamed when the service streams). The app now uses POST /microservices/agent/table-chat/ instead.
Auth: Session token
Request body (application/json)
| Field | Type | Required | Description |
|---|---|---|---|
table_id | string | no | |
params | object | no | Service parameters (query, …). |
Response 200 — Streamed or JSON answer.
Example
bash
curl -X POST "https://api.example.com/microservices/data-extractor/chat" \
-H "Authorization: Token $FINBLADE_TOKEN"POST /microservices/agent/table-chat/
Ask the assistant about a table
The same contract as POST /microservices/agent/chat/ (see Chat AI), bound to one extracted table: table_id is required and authorised (owner or granted), the skill is pinned to the table desk, and the agent can only read and edit that table. Use a fresh conversation_id per table.
Auth: Session token · In the app: Apps → Databases → table → Chat
Query parameters
| Field | Type | Required | Description |
|---|---|---|---|
timeout | integer | no | Default: 600. |
Request body (application/json)
| Field | Type | Required | Description |
|---|---|---|---|
conversation_id | string | yes | |
message | string | yes | |
table_id | string | yes | |
chat_session_id | integer | no | |
reasoning_effort | string | no |
json
{
"conversation_id": "4d3c2b1a-9e8f-4a7b-8c6d-5e4f3a2b1c0d",
"message": "Which supplier has the highest total this month?",
"table_id": "tbl_9f8e7d6c"
}Response 200 — The agent's reply (see AgentChatReply).
| Field | Type | Description |
|---|---|---|
status | string | completed — answer holds the reply. queued — the turn is queued behind another one; the reply will arrive on the ws/chat/{conversation_id} socket. missing_param, clarification, interrupted — the agent needs input; the question is in message. |
answer | string | The reply (Markdown). |
message | string | The agent's question when it needs input. |
turn_id | string | |
queue_position | integer | |
mgid | string | Present when the turn produced a dashboard chart (fetch it with GET /microservices/dashboard-data/?mgid=). |
dashboard_id | string | Present when the turn published a Studio artifact. |
generated_files_urls | string[] | Media URLs of files the turn produced (documents, images). Sign them to download. |
json
{
"status": "completed",
"turn_id": "7c1f0c1e-2b8f-4a6e-9c0a-1e4b6f2d3a55",
"answer": "Q3 revenue grew **12.4% year over year**, driven by the enterprise segment (+19%) …\n",
"generated_files_urls": []
}Response 400 — table_id missing.
Response 403 — No access to the table.
Example
bash
curl -X POST "https://api.example.com/microservices/agent/table-chat/" \
-H "Authorization: Token $FINBLADE_TOKEN" \
-H "Content-Type: application/json" \
-d '{"conversation_id":"4d3c2b1a-9e8f-4a7b-8c6d-5e4f3a2b1c0d","message":"Which supplier has the highest total this month?","table_id":"tbl_9f8e7d6c"}'GET /microservices/data-extractor/tables_database
List my table databases
Auth: Session token · In the app: Apps → Databases
Query parameters
| Field | Type | Required | Description |
|---|---|---|---|
organization_name | string | no |
Response 200 — Databases (service response).
| Field | Type | Description |
|---|---|---|
count | integer | Number of databases returned. |
tables_databases | object[] | |
tables_databases[].tables_database_id | string | |
tables_databases[].name | string | |
tables_databases[].email | string | |
tables_databases[].organization_name | string | |
tables_databases[].table_ids | string[] | |
tables_databases[].tables_count | integer | |
tables_databases[].created_at | string (date-time) | |
tables_databases[].updated_at | string (date-time) |
Example
bash
curl -X GET "https://api.example.com/microservices/data-extractor/tables_database" \
-H "Authorization: Token $FINBLADE_TOKEN"POST /microservices/data-extractor/tables_database
Create a table database
Auth: Session token
Request body (application/json)
| Field | Type | Required | Description |
|---|---|---|---|
name | string | yes | |
table_ids | string[] | no |
json
{
"name": "Finance",
"table_ids": [
"tbl_9f8e7d6c"
]
}Response 200 — Created (service response with tables_database_id).
| Field | Type | Description |
|---|---|---|
tables_database_id | string | |
name | string | |
email | string | |
organization_name | string | |
table_ids | string[] | |
tables_count | integer | |
created_at | string (date-time) | |
updated_at | string (date-time) |
json
{
"tables_database_id": "db_3c2b1a",
"name": "Finance",
"email": "jane@acme.com",
"organization_name": "Acme",
"table_ids": [
"tbl_9f8e7d6c"
],
"tables_count": 1,
"created_at": "2026-09-02T09:00:00Z",
"updated_at": "2026-09-22T08:05:41Z"
}Example
bash
curl -X POST "https://api.example.com/microservices/data-extractor/tables_database" \
-H "Authorization: Token $FINBLADE_TOKEN" \
-H "Content-Type: application/json" \
-d '{"name":"Finance","table_ids":["tbl_9f8e7d6c"]}'GET /microservices/data-extractor/tables_database/{db_id}
Get a table database
Auth: Session token
Path parameters
| Field | Type | Required | Description |
|---|---|---|---|
db_id | string | yes |
Response 200 — The database.
| Field | Type | Description |
|---|---|---|
tables_database_id | string | |
name | string | |
email | string | |
organization_name | string | |
table_ids | string[] | |
tables_count | integer | |
created_at | string (date-time) | |
updated_at | string (date-time) |
json
{
"tables_database_id": "db_3c2b1a",
"name": "Finance",
"email": "jane@acme.com",
"organization_name": "Acme",
"table_ids": [
"tbl_9f8e7d6c"
],
"tables_count": 1,
"created_at": "2026-09-02T09:00:00Z",
"updated_at": "2026-09-22T08:05:41Z"
}Response 403 — Not yours.
Example
bash
curl -X GET "https://api.example.com/microservices/data-extractor/tables_database/<db_id>" \
-H "Authorization: Token $FINBLADE_TOKEN"PUT /microservices/data-extractor/tables_database/{db_id}
Rename or re-order a table database
Auth: Session token
Path parameters
| Field | Type | Required | Description |
|---|---|---|---|
db_id | string | yes |
Request body (application/json)
| Field | Type | Required | Description |
|---|---|---|---|
name | string | no | |
table_ids | string[] | no |
Response 200 — Updated.
Example
bash
curl -X PUT "https://api.example.com/microservices/data-extractor/tables_database/<db_id>" \
-H "Authorization: Token $FINBLADE_TOKEN"DELETE /microservices/data-extractor/tables_database/{db_id}
Delete a table database
Deletes the grouping, not the tables.
Auth: Session token
Path parameters
| Field | Type | Required | Description |
|---|---|---|---|
db_id | string | yes |
Response 200 — Deleted.
Example
bash
curl -X DELETE "https://api.example.com/microservices/data-extractor/tables_database/<db_id>" \
-H "Authorization: Token $FINBLADE_TOKEN"