Query tasks from a Workstation (App) with powerful filtering capabilities. This endpoint allows you to filter by metadata (status, dates, tags) and by extracted data fields using MongoDB-style operators.
Basic Query
const API_KEY = process.env.TELA_API_KEY;
const response = await fetch('https://api.tela.com/task/query', {
method: 'POST',
headers: {
'Authorization': `Bearer ${API_KEY}`,
'Content-Type': 'application/json'
},
body: JSON.stringify({
promptApplicationId: "your-app-uuid",
limit: 20
})
});
const data = await response.json();
console.log(data);
Filter tasks by status, creation date, approval date, tags, and more.
const response = await fetch('https://api.tela.com/task/query', {
method: 'POST',
headers: {
'Authorization': `Bearer ${API_KEY}`,
'Content-Type': 'application/json'
},
body: JSON.stringify({
promptApplicationId: "your-app-uuid",
filters: {
status: ["approved", "completed"],
createdAtSince: "2025-01-01T00:00:00Z",
createdAtUntil: "2025-01-31T23:59:59Z",
approvedBy: ["[email protected]"],
tags: ["priority", "reviewed"]
},
orderBy: "createdAt",
order: "desc",
limit: 50
})
});
The most powerful feature is filtering by the data extracted from your documents. Use MongoDB-style operators to query any field in your task’s output.
Simple Equality
const response = await fetch('https://api.tela.com/task/query', {
method: 'POST',
headers: {
'Authorization': `Bearer ${API_KEY}`,
'Content-Type': 'application/json'
},
body: JSON.stringify({
promptApplicationId: "your-app-uuid",
outputQuery: {
"cliente": "Acme Corporation",
"status": "active"
}
})
});
Comparison Operators
const response = await fetch('https://api.tela.com/task/query', {
method: 'POST',
headers: {
'Authorization': `Bearer ${API_KEY}`,
'Content-Type': 'application/json'
},
body: JSON.stringify({
promptApplicationId: "your-app-uuid",
outputQuery: {
// Numeric comparisons
"valor": { "$gte": 100000, "$lte": 500000 },
// Date comparisons
"dataVencimento": { "$lte": "2025-03-31" },
// Text search (case-insensitive)
"descricao": { "$contains": "compliance" },
// Value in list
"categoria": { "$in": ["financeiro", "juridico"] }
}
})
});
Querying Nested Arrays with $elemMatch
When your extracted data contains arrays (e.g., line items, categories, participants), use $elemMatch to query elements within those arrays.
$elemMatch supports nesting, so you can query deeply nested structures like categories[].items[].price.
// Example: Find menus that have any item under $10
const response = await fetch('https://api.tela.com/task/query', {
method: 'POST',
headers: {
'Authorization': `Bearer ${API_KEY}`,
'Content-Type': 'application/json'
},
body: JSON.stringify({
promptApplicationId: "your-app-uuid",
outputQuery: {
"categories": {
"$elemMatch": {
"items": {
"$elemMatch": {
"price": { "$lt": 10 }
}
}
}
}
}
})
});
More $elemMatch Examples
// Find invoices with any line item over $1000
{
"outputQuery": {
"lineItems": {
"$elemMatch": {
"amount": { "$gt": 1000 }
}
}
}
}
// Find contracts with a specific signatory
{
"outputQuery": {
"signatories": {
"$elemMatch": {
"name": { "$contains": "John" },
"role": "CEO"
}
}
}
}
// Find menus with vegan options in the beverages category
{
"outputQuery": {
"categories": {
"$elemMatch": {
"category_name": "BEVERAGES",
"items": {
"$elemMatch": {
"dietary_tags": { "$contains": "Vegan" }
}
}
}
}
}
}
Select Specific Fields
Reduce response size by selecting only the fields you need from the extracted data.
const response = await fetch('https://api.tela.com/task/query', {
method: 'POST',
headers: {
'Authorization': `Bearer ${API_KEY}`,
'Content-Type': 'application/json'
},
body: JSON.stringify({
promptApplicationId: "your-app-uuid",
outputQuery: {
"valor": { "$gt": 100000 }
},
select: ["cliente", "valor", "dataVencimento", "status"]
})
});
Use limit and offset for paginating through large result sets.
// First page
const page1 = await fetch('https://api.tela.com/task/query', {
method: 'POST',
headers: {
'Authorization': `Bearer ${API_KEY}`,
'Content-Type': 'application/json'
},
body: JSON.stringify({
promptApplicationId: "your-app-uuid",
limit: 20,
offset: 0
})
});
// Second page
const page2 = await fetch('https://api.tela.com/task/query', {
method: 'POST',
headers: {
'Authorization': `Bearer ${API_KEY}`,
'Content-Type': 'application/json'
},
body: JSON.stringify({
promptApplicationId: "your-app-uuid",
limit: 20,
offset: 20
})
});
Request Body
| Field | Type | Required | Description |
|---|
promptApplicationId | string | Yes | UUID of the Workstation/App to query |
filters | object | No | Metadata filters (see below) |
outputQuery | object | No | Filters on extracted data fields |
select | string[] | No | Fields to return from output. If empty, returns all fields |
limit | number | No | Max results to return (1-100, default: 50) |
offset | number | No | Number of results to skip (default: 0) |
orderBy | string | No | Sort field: createdAt, updatedAt, approvedAt, or name |
order | string | No | Sort direction: asc or desc |
Filters Object
| Field | Type | Description |
|---|
status | string[] | Filter by task status (e.g., ["approved", "completed"]) |
createdAtSince | string | Tasks created after this ISO datetime |
createdAtUntil | string | Tasks created before this ISO datetime |
approvedAtSince | string | Tasks approved after this ISO datetime |
approvedAtUntil | string | Tasks approved before this ISO datetime |
approvedBy | string[] | Filter by approver email addresses |
createdBy | string[] | Filter by creator email addresses |
tags | string[] | Filter by task tags |
Output Query Operators
| Operator | Example | Description |
|---|
| (none) | "field": "value" | Exact equality match |
$gt | { "$gt": 100 } | Greater than |
$gte | { "$gte": 100 } | Greater than or equal |
$lt | { "$lt": 100 } | Less than |
$lte | { "$lte": 100 } | Less than or equal |
$eq | { "$eq": 100 } | Explicit equality |
$ne | { "$ne": 100 } | Not equal |
$in | { "$in": ["a", "b"] } | Value in array |
$contains | { "$contains": "text" } | Case-insensitive text search |
$elemMatch | { "$elemMatch": {...} } | Match element in array |
$type | { "$gt": "100", "$type": "number" } | Override type inference |
Type Inference
The system automatically infers data types from values:
| Value Format | Inferred Type | SQL Cast |
|---|
100, 3.14 | number | ::numeric |
true, false | boolean | ::boolean |
"2025-03-01" | date | ::date |
"2025-03-01T10:00:00Z" | timestamp | ::timestamp |
| Other strings | string | (none) |
Use $type to override when needed:
{ "codigo": { "$gt": "100", "$type": "number" } }
Response
{
"data": [
{
"taskId": "550e8400-e29b-41d4-a716-446655440000",
"taskName": "Invoice-2025-001.pdf",
"status": "approved",
"createdAt": "2025-01-15T10:30:00Z",
"approvedAt": "2025-01-15T11:00:00Z",
"output": {
"cliente": "Acme Corporation",
"valor": 150000,
"dataVencimento": "2025-03-31"
}
}
],
"meta": {
"totalCount": 142,
"limit": 20,
"offset": 0,
"currentPage": 1,
"totalPages": 8
}
}
Response Fields
| Field | Type | Description |
|---|
data | array | Array of matching tasks |
data[].taskId | string | Unique task identifier |
data[].taskName | string | Task name (usually the document filename) |
data[].status | string | Current task status |
data[].createdAt | string | ISO datetime when task was created |
data[].approvedAt | string | null | ISO datetime when task was approved |
data[].output | object | Extracted data (all fields or selected fields) |
meta.totalCount | number | Total number of matching tasks |
meta.limit | number | Results per page |
meta.offset | number | Number of results skipped |
meta.currentPage | number | Current page number |
meta.totalPages | number | Total number of pages |
Error Responses
| Status | Description |
|---|
400 | Invalid request body or malformed query |
401 | Missing or invalid data token |
403 | Token doesn’t have access to the specified app |
404 | App not found |
500 | Internal server error |