# Documentation Index

Fetch the complete documentation index at: [/llms.txt](https://docs.flows.super.ai/llms.txt)

Use this file to discover all available pages before exploring further.

This guide shows you how to authenticate, run your first workflow, and retrieve results.

## Process a document in 60 seconds

Run this single script to authenticate, create a flow, and process your first invoice:

# Replace with your credentials
    EMAIL="your-email@example.com"
    PASSWORD="your-password"

# Get anonymous key and authenticate
    ANON_KEY=$(curl -s https://flows.super.ai/api/auth/anon-key | jq -r .anon_key)
    TOKEN=$(curl -s -X POST "https://core.flows.super.ai/auth/v1/token?grant_type=password" \
      -H "Content-Type: application/json" \
      -H "apikey: $ANON_KEY" \
      -d "{\"email\":\"$EMAIL\",\"password\":\"$PASSWORD\"}" | jq -r .access_token)

# Create flow with full definition
    FLOW_RESPONSE=$(curl -s -X POST https://flows.super.ai/api/flows \
      -H "Authorization: Bearer $TOKEN" \
      -H "Content-Type: application/json" \
      -d '{\n  "display_name": "Quick Start: Invoice Processing",\n  "description": "Extract and validate invoice data",\n  "version": 1,\n  "definition": {\n    "flow": {"created_at": "", "author_uuid": ""},\n    "flow_configs": [{\n      "config": {\n        "tasks": [\n          {\n            "visual_properties": {"position": {"x": 0, "y": 359}},\n            "name": "8a0883ff-e0b9-4c27-8dfe-8af18c7d3ea4",\n            "task_executor_name": "receive_file",\n            "task_title": "Receive File",\n            "parameters": {}\n          },\n          {\n            "visual_properties": {"position": {"x": 530, "y": 232}},\n            "name": "d61f3643-52d9-4ff3-bee7-7a3e26ca013f",\n            "task_executor_name": "doc_to_text",\n            "task_title": "Convert Document to Text",\n            "parameters": {\n              "worker": "gpt-4.1",\n              "mime_type": "{{8a0883ff-e0b9-4c27-8dfe-8af18c7d3ea4.mime_type}}",\n              "document_url": "{{8a0883ff-e0b9-4c27-8dfe-8af18c7d3ea4.document_url}}",\n              "doc_representation": "whitespace"\n            }\n          },\n          {\n            "visual_properties": {"position": {"x": 1060, "y": 0}},\n            "name": "ce65d796-fabe-4b05-be0e-e58182fdae98",\n            "task_executor_name": "text_to_structured",\n            "task_title": "Extract Invoice Data",\n            "parameters": {\n              "fields": [\n                {"id": "invoice_no", "title": "Invoice Number", "data_type": "string", "instructions": ""},\n                {"id": "total", "title": "total", "data_type": "float", "instructions": "identify the total amount"},\n                {"id": "account_owner", "title": "Account Owner", "data_type": "string", "instructions": "Identify the account owner"}\n              ],\n              "worker": "gpt-4.1",\n              "input_data": "{{d61f3643-52d9-4ff3-bee7-7a3e26ca013f.page_contents}}",\n              "document_url": "{{d61f3643-52d9-4ff3-bee7-7a3e26ca013f.document_url}}",\n              "extract_bounding_boxes": true,\n              "use_logprobs_confidence": true\n            }\n          },\n          {\n            "visual_properties": {"position": {"x": 1590, "y": 285}},\n            "name": "2dad3105-b031-4681-9588-0709b487034c",\n            "task_executor_name": "collection_validation",\n            "task_title": "Validate Invoice Total",\n            "parameters": {\n              "validators": [{"name": "Not Empty Validation"}],\n              "input_collection": "{{ce65d796-fabe-4b05-be0e-e58182fdae98.total}}"\n            }\n          }\n        ]\n      }\n    }]\n  }\n}')

FLOW_ID=$(echo "$FLOW_RESPONSE" | jq -r .id)
    echo "Flow created: $FLOW_ID"

# Execute the flow with a sample invoice
    EXEC_RESPONSE=$(curl -s -X POST https://flows.super.ai/api/flow-executions \
      -H "Authorization: Bearer $TOKEN" \
      -H "Content-Type: application/json" \
      -d '{"flow_id":"$FLOW_ID","input":{"filename":"invoice-example.pdf","mime_type":"application/pdf","document_url":"https://cdn.super.ai/invoice-example.pdf"}}')

EXEC_ID=$(echo "$EXEC_RESPONSE" | jq -r .id)
    echo "Execution started: $EXEC_ID"
    echo "View results: https://flows.super.ai/flows/$FLOW_ID?view=data"

What just happened?

1. **Authenticated** with your SuperAI account.
2. **Created a 4-task invoice processing flow**: Receive File → Convert to Text → Extract Invoice Data → Validate.
3. **Started processing** a sample invoice PDF.
4. Got back a flow ID and execution ID to track progress.

Check the dashboard link to watch your flow process the document. Got an error? Jump to [Troubleshooting](https://docs.flows.super.ai/quickstart#troubleshooting).

## What are SuperAI Flows?

SuperAI Flows automate multi-step document processing pipelines. A typical flow:

1. Classifies documents (invoice, receipt, contract)
2. Extracts structured data based on document type
3. Validates extracted values
4. Delivers results via webhook or API

## Flow definition example

Flows are defined in declarative YAML that’s both human-readable and type-safe. Here’s a complete document processing workflow:

tasks:
      - name: classify_document
        task_executor_name: document_classifier
        parameters:
          document_url: "{{input.document_url}}"
          document_types:
            - invoice
            - bank_statement
            - contract

- name: extract_data
        task_executor_name: text_to_structured
        parameters:
          document_url: "{{classify_document.splits[0].document_url}}"
          fields:
            - id: invoice_number
              data_type: string
            - id: total_amount
              data_type: float
              instructions: "identify the total amount"

- name: validate_results
        task_executor_name: collection_validation
        parameters:
          input_collection: "{{extract_data.total_amount}}"
          validators:
            - name: Not Empty Validation

Key features:

- **Task chaining** — `extract_data` references output from `classify_document` using `{{classify_document.splits[0].document_url}}`
- **Type safety** — Each field specifies a `data_type` (string, float, etc.)
- **Built-in executors** — Use pre-built task executors like `document_classifier` and `text_to_structured`
- **Validation** — Chain validation tasks to ensure data quality

The platform automatically resolves dependencies, handles retries, and manages data flow between tasks.

## Prerequisites

- A SuperAI account ( [sign up free](https://flows.super.ai/))
- Your login email and password
- `curl` and `jq` installed (for testing examples)

## Authentication

SuperAI uses JWT-based authentication. All API requests require a valid access token.

1

Get the anonymous key

This is a public endpoint — no auth required.

curl https://flows.super.ai/api/auth/anon-key

{ "anon_key": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..." }

2

Exchange credentials for JWT tokens

curl -X POST 'https://core.flows.super.ai/auth/v1/token?grant_type=password' \
      -H 'Content-Type: application/json' \
      -H 'apikey: YOUR_ANON_KEY' \
      -d '{"email": "your-email@example.com", "password": "your-password"}'

{
      "access_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
      "refresh_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
      "expires_in": 3600,
      "token_type": "bearer"
    }

3

Use the access token in every request

curl https://flows.super.ai/api/flows \
      -H "Authorization: Bearer YOUR_ACCESS_TOKEN"

### Token management

| Token type       | Lifetime | When to use                                     |
| ---------------- | -------- | ----------------------------------------------- |
| **Access token** | 1 hour   | Include in every API request                    |
| **Refresh token**| 30 days  | Get new access tokens when expired              |

Tokens grant full account access — treat them like passwords. Store them in environment variables or secret managers, never in code, and always use HTTPS.

When your access token expires, use the refresh token to get a new one without re-authenticating:

curl -X POST 'https://core.flows.super.ai/auth/v1/token?grant_type=refresh_token' \
      -H 'Content-Type: application/json' \
      -H 'apikey: YOUR_ANON_KEY' \
      -d '{"refresh_token": "YOUR_REFRESH_TOKEN"}'

## Run your first flow

Start a flow by creating a flow execution with your input data.

curl -X POST https://flows.super.ai/api/flow-executions \
      -H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
      -H "Content-Type: application/json" \
      -d '{
        "flow_id": "YOUR_FLOW_ID",
        "input": {
          "filename": "invoice-example.pdf",
          "mime_type": "application/pdf",
          "document_url": "https://cdn.super.ai/invoice-example.pdf"
        }
      }'

{
      "id": "df77dc65-909b-430e-bff1-9e9ecf315a80",
      "flow_id": "550e8400-e29b-41d4-a716-446655440000",
      "flow_version": 1,
      "status": "running",
      "input": {
        "filename": "invoice-example.pdf",
        "mime_type": "application/pdf",
        "document_url": "https://cdn.super.ai/invoice-example.pdf"
      },
      "organization_id": "660e8400-e29b-41d4-a716-446655440001",
      "created_at": "2024-01-15T10:30:00Z",
      "updated_at": "2024-01-15T10:30:00Z"
    }

Key fields:

- `id` — The flow execution ID (use this to check status and retrieve results)
- `status` — Current execution state (`running`, `completed`, `failed`)
- `flow_version` — Version of the flow used (remains constant even if the flow is updated)

The input object structure depends on your flow’s configuration. For file-based flows, provide `filename`, `mime_type`, and `document_url`. Other flows may have different input schemas — check the flow’s `input_schema`.

### Check execution status

curl "https://flows.super.ai/api/flow-executions/df77dc65-909b-430e-bff1-9e9ecf315a80" \
      -H "Authorization: Bearer YOUR_ACCESS_TOKEN"

{
      "id": "df77dc65-909b-430e-bff1-9e9ecf315a80",
      "flow_id": "550e8400-e29b-41d4-a716-446655440000",
      "status": "completed",
      "created_at": "2024-01-15T10:30:00Z",
      "updated_at": "2024-01-15T10:32:45Z"
    }

## Retrieve results

Get task execution results for your flow:

curl "https://flows.super.ai/api/task-executions?flow_execution_id=df77dc65-909b-430e-bff1-9e9ecf315a80" \
      -H "Authorization: Bearer YOUR_ACCESS_TOKEN"

{
      "task_executions": [\
        {\
          "id": "e47f2923-1205-4bf2-bee2-2974ddb64aad",\
          "task_name": "extract_invoice_data",\
          "status": "completed",\
          "output": {\
            "invoice_number": "INV-0052465571",\
            "total_amount": 2435.00,\
            "currency": "USD",\
            "vendor": "Acme Corp",\
            "date": "2024-01-15"\
          },\
          "created_at": "2024-01-15T10:30:05Z",\
          "updated_at": "2024-01-15T10:32:40Z"\
        }\
      ]
    }

Common query parameters:

- `flow_execution_id` — Filter by flow execution (required for most queries)
- `task_name` — Filter by specific task name
- `task_execution_idx` — Filter by execution attempt (0 = first attempt, 1 = first retry)

## Webhooks (recommended)

Instead of polling for results, configure webhooks to receive real-time notifications when flows complete. The Webhook Notification task sends POST requests to your specified URL. Add a Webhook Notification task to your flow with these parameters:

- **Url** (required) — Your webhook endpoint URL
- **Authorization Header Value** (optional) — Auth token or API key for securing your webhook
- **Payload** (required) — The data to send (can reference task outputs using `{{task_name.field}}` syntax)

Example payload:

{
      "event_type": "flow_execution.completed",
      "flow_id": "550e8400-e29b-41d4-a716-446655440000",
      "flow_execution_id": "df77dc65-909b-430e-bff1-9e9ecf315a80",
      "status": "completed",
      "timestamp": "2024-01-15T10:32:45Z",
      "data": {
        "task_outputs": {
          "extract_invoice_data": {
            "invoice_number": "INV-0052465571",
            "total_amount": 2435.00
          }
        }
      }
    }

Your webhook endpoint should validate the authorization header (if provided via the `x-webhook-token` header), process the payload, and return a 2xx status code to acknowledge receipt.

## Troubleshooting

Authentication failed / Invalid credentials

- Verify your credentials work in the web UI first at [flows.super.ai](https://flows.super.ai/).
- Check for special characters in your password; wrap it in single quotes to preserve them: `export PASSWORD='your-password'`.
- Verify the anonymous key is valid — it should be a long JWT string.

Flow not found (404)

- Verify the flow was created successfully (check the flow creation response).
- List all flows you have access to: `curl https://flows.super.ai/api/flows -H "Authorization: Bearer $TOKEN"`.
- Confirm you’re using the correct UUID and are logged into the correct organization — flows are organization-specific.

Unauthorized (401) mid-session

Your token expired after 1 hour. Use the refresh token to obtain a new access token (see [Authentication](https://docs.flows.super.ai/quickstart#authentication)).

Bad Request (400) when creating an execution

- Validate your JSON is well-formed (pipe it through `jq`).
- For custom flows, check the required input schema: `curl "https://flows.super.ai/api/flows/$FLOW_ID" -H "Authorization: Bearer $TOKEN" | jq .input_schema`.

Execution stuck in 'running'

Some flows take minutes for complex documents. Use webhooks instead of polling, and inspect task executions to see which task is blocking: `curl "https://flows.super.ai/api/task-executions?flow_execution_id=$EXEC_ID" -H "Authorization: Bearer $TOKEN" | jq '.task_executions[] | {task_name, status}'`.

Rate limiting (429)

The API implements fair-use rate limiting. If you receive 429 (Too Many Requests), wait before retrying and implement exponential backoff.

Still stuck? Check [status.super.ai](https://status.super.ai/), then contact [support@super.ai](mailto:support@super.ai) with your flow execution ID and the `request_id` from any error responses.

## Error handling

The API uses standard HTTP status codes:

| Code | Meaning    | Example                              |
|------|------------|--------------------------------------|
| 200  | Success    | Request completed successfully        |
| 201  | Created    | Flow execution created                |
| 400  | Bad Request | Invalid input data or missing fields |
| 401  | Unauthorized| Missing or invalid access token      |
| 403  | Forbidden   | Insufficient permissions             |
| 404  | Not Found   | Flow or execution ID doesn’t exist  |
| 422  | Validation Error | Request body failed validation   |
| 500  | Server Error | Internal error                       |

Errors follow a consistent format. See the full [Error Codes reference](https://docs.flows.super.ai/api-reference/errors).

{
      "error": {
        "code": "not_found",
        "message": "Flow not found"
      },
      "request_id": "01K8KACP7D2XFGHJ9KLM4NPQR8"
    }

## Next steps

[**Downloading files** \
\
Retrieve `gs://` files returned in your flow outputs.](https://docs.flows.super.ai/guides/downloading-files)

[**API Reference** \
\
Full endpoint documentation with schemas.](https://docs.flows.super.ai/api-reference/introduction)
