Built-in Tables
In addition to custom tables you create, every project includes read-only built-in tables in the abstra schema. These tables give you SQL access to workflow data like tasks, users, roles, and executions.
Read-only access
Built-in tables are accessible via SQL SELECT queries only. All writes go through the Abstra API and Python SDK.
Querying built-in tables
Use the abstra schema prefix when querying:
import abstra.tables as at
tasks = at.run_sql("SELECT * FROM abstra.tasks WHERE status = 'pending' LIMIT 10")
users = at.run_sql("SELECT * FROM abstra.users")
Available tables
abstra.tasks
Stores all workflow tasks and their lifecycle data.
| Column | Type | Description |
|---|---|---|
id | uuid | Task ID |
created_at | timestamp | When the task was created |
updated_at | timestamp | Last update |
deleted_at | timestamp | Soft delete timestamp (null if active) |
project_id | uuid | Project ID |
type | varchar | Task type label used for routing |
payload | jsonb | Task payload data |
status | text | pending, locked, or completed |
target_stage_id | varchar | Destination stage ID |
created_by_stage_id | varchar | Stage that created this task |
created_by_execution_id | uuid | Execution that created this task |
completed_at | timestamp | When the task was completed |
completed_by | uuid | Execution that completed this task |
locked_at | timestamp | When the task was locked |
locked_by | uuid | Execution that locked this task |
abstra.executions
Records every stage execution in your workflow.
| Column | Type | Description |
|---|---|---|
id | uuid | Execution ID |
created_at | timestamp | When the execution started |
updated_at | timestamp | Last status change |
status | text | created, running, success, failure, etc. |
context | jsonb | Execution context (includes taskId if triggered by a task) |
project_id | uuid | Project ID |
build_id | uuid | Build that ran this execution |
stage_id | text | Stage identifier |
stage_run_id | uuid | Stage run ID (for forms threads) |
worker_id | uuid | Worker that ran the execution |
app_id | uuid | App ID (if applicable) |
pid | text | Process ID |
abstra.users
Stores access control users for your project.
| Column | Type | Description |
|---|---|---|
id | uuid | User ID |
created_at | timestamp | When the user was added |
updated_at | timestamp | Last update |
deleted_at | timestamp | Soft delete timestamp |
email | varchar | User email |
project_id | uuid | Project ID |
abstra.roles
Stores access control roles.
| Column | Type | Description |
|---|---|---|
id | uuid | Role ID |
created_at | timestamp | When the role was created |
updated_at | timestamp | Last update |
deleted_at | timestamp | Soft delete timestamp |
project_id | uuid | Project ID |
name | varchar | Role name |
description | varchar | Role description |
abstra.users_roles
Junction table linking users to roles.
| Column | Type | Description |
|---|---|---|
id | uuid | Association ID |
created_at | timestamp | When the association was created |
deleted_at | timestamp | Soft delete timestamp |
user_id | uuid | References abstra.users.id |
role_id | uuid | References abstra.roles.id |
abstra.signup_policy
Stores email pattern rules for user sign-up.
| Column | Type | Description |
|---|---|---|
id | uuid | Policy ID |
project_id | uuid | Project ID |
email_patterns | jsonb | Array of allowed email patterns (e.g. ["@company.com"]) |
Example queries
Pending tasks by stage
import abstra.tables as at
pending = at.run_sql("""
SELECT target_stage_id, count(*) as pending_count
FROM abstra.tasks
WHERE status = 'pending' AND deleted_at IS NULL
GROUP BY target_stage_id
""")
Recent failed executions
import abstra.tables as at
failures = at.run_sql("""
SELECT id, stage_id, created_at, context
FROM abstra.executions
WHERE status = 'failure'
ORDER BY created_at DESC
LIMIT 20
""")
Users with their roles
import abstra.tables as at
users_with_roles = at.run_sql("""
SELECT u.email, array_agg(r.name) as roles
FROM abstra.users u
LEFT JOIN abstra.users_roles ur ON u.id = ur.user_id AND ur.deleted_at IS NULL
LEFT JOIN abstra.roles r ON ur.role_id = r.id AND r.deleted_at IS NULL
WHERE u.deleted_at IS NULL
GROUP BY u.email
""")