> ## Documentation Index
> Fetch the complete documentation index at: https://docs.triform.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Payloads

> Structure input data for Projects, Flows, and Agents

## What is a Payload?

A Payload is the input data you provide when executing a Project, Flow, Agent, or Action. It's a JSON object that contains all the information needed for that execution.

Think of it as:

* The **arguments** to a function
* The **request body** of an API call
* The **input** to your system

## Why Payloads

* Speed — One‑click reruns for common cases.
* Reproducibility — Lock in known‑good inputs as your baseline.
* Documentation — Show how a component is intended to be used.

## Good Payloads include

* Minimal required fields with realistic values.
* Edge‑case variants (empty, large, malformed types).
* Comments or README references for context.

## Workflow

1. Create a Payload for a Node (Action/Flow).
2. Refine the Node until the output is acceptable.
3. Keep the Payload as a regression check when you iterate.

> tip: Name by intent — Prefer names like `minimal`, `typical_customer`, `edge_empty_messages` over `test1`, `test2`.

## Payload structure

### Basic payload

```json
{
  "field1": "value",
  "field2": 123,
  "field3": true
}
```

### Nested payload

```json
{
  "user": {
    "id": "user_123",
    "email": "alice@example.com",
    "tier": "premium"
  },
  "action": "process_order",
  "items": [
    {"id": "item_1", "quantity": 2},
    {"id": "item_2", "quantity": 1}
  ]
}
```

### Payload with metadata

```json
{
  "data": {
    "user_input": "Summarize this article..."
  },
  "config": {
    "format": "bullets",
    "max_length": 200
  },
  "metadata": {
    "request_id": "req_xyz",
    "source": "web_app"
  }
}
```

## Payload schema

The schema defines what fields are expected, their types, and validation rules.

### Defining a schema

In your Project/Flow Input node:

```json
{
  "user_id": {
    "type": "string",
    "required": true,
    "description": "Unique user identifier"
  },
  "action": {
    "type": "enum",
    "options": ["create", "update", "delete"],
    "required": true,
    "description": "Operation to perform"
  },
  "data": {
    "type": "object",
    "required": false,
    "description": "Operation-specific data"
  },
  "options": {
    "type": "object",
    "required": false,
    "default": {},
    "description": "Optional configuration"
  }
}
```

### Data types

| Type      | Example                                 | Description      |
| --------- | --------------------------------------- | ---------------- |
| `string`  | `"hello"`                               | Text             |
| `number`  | `42`, `3.14`                            | Integer or float |
| `boolean` | `true`, `false`                         | True/false       |
| `array`   | `[1, 2, 3]`                             | List of items    |
| `object`  | `{"key": "value"}`                      | Nested structure |
| `enum`    | `"red"` from `["red", "green", "blue"]` | Fixed options    |
| `null`    | `null`                                  | Absence of value |

### Required vs. optional

**Required fields:**

* Must be present in every payload
* Execution fails if missing
* No default value

**Optional fields:**

* Can be omitted
* Can have default values
* Execution continues without them

**Example:**

```json
{
  "required_field": "must be here",
  "optional_field": "can be omitted"
}
```

## Creating payloads

### In the UI

1. Select your Project/Flow/Agent
2. Go to **Properties → Execute**
3. Enter payload in the JSON editor
4. Click **Execute**

**Tips:**

* Use the schema viewer to see expected fields
* Auto-complete helps with field names
* Syntax highlighting catches errors

### Via API

```bash
curl -X POST https://api.triform.ai/v1/your-project/execute \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "user_id": "123",
    "action": "process",
    "data": {"value": 42}
  }'
```

### Programmatically

**Python:**

```python
import requests

payload = {
    "user_id": "123",
    "action": "process",
    "data": {"value": 42}
}

response = requests.post(
    "https://api.triform.ai/v1/your-project/execute",
    headers={
        "Authorization": f"Bearer {API_KEY}",
        "Content-Type": "application/json"
    },
    json=payload
)

result = response.json()
```

**JavaScript:**

```javascript
const payload = {
  user_id: "123",
  action: "process",
  data: { value: 42 }
};

const response = await fetch(
  "https://api.triform.ai/v1/your-project/execute",
  {
    method: "POST",
    headers: {
      "Authorization": `Bearer ${API_KEY}`,
      "Content-Type": "application/json"
    },
    body: JSON.stringify(payload)
  }
);

const result = await response.json();
```

## Payload validation

Triform validates payloads against the schema before execution.

### Common validation errors

**Missing required field:**

```json
{
  "error": "ValidationError",
  "message": "Missing required field: user_id",
  "field": "user_id"
}
```

**Wrong type:**

```json
{
  "error": "ValidationError",
  "message": "Expected number but got string",
  "field": "age",
  "expected": "number",
  "actual": "string"
}
```

**Invalid enum value:**

```json
{
  "error": "ValidationError",
  "message": "Invalid value for action. Must be one of: create, update, delete",
  "field": "action",
  "value": "invalid_action",
  "allowed": ["create", "update", "delete"]
}
```

**Out of range:**

```json
{
  "error": "ValidationError",
  "message": "Value must be between 0 and 100",
  "field": "percentage",
  "value": 150,
  "min": 0,
  "max": 100
}
```

## Saved payloads

Save frequently-used payloads for quick testing.

### Saving a payload

1. Enter payload in Execute panel
2. Click **Save Payload**
3. Name it: `Test Case 1: Happy Path`
4. Click **Save**

### Loading a saved payload

1. Go to Execute panel
2. Click **Load Payload**
3. Select from list
4. Click **Load**
5. Optionally modify
6. Execute

### Payload library

Organize saved payloads:

**By category:**

* Happy path examples
* Edge cases
* Error scenarios
* Performance tests
* Regression tests

**By purpose:**

* `demo_payload` — For demonstrations
* `test_minimal` — Minimum required fields
* `test_full` — All fields populated
* `test_edge_empty_list` — Edge case testing

## Payload best practices

> **Provide examples** — Include sample payloads in documentation

> **Use meaningful values** — `"user_123"` is better than `"test"`

> **Test edge cases** — Empty arrays, null values, max sizes

> **Save regression tests** — Keep payloads that found bugs

> **Document schema** — Clear descriptions for each field

> **Version payloads** — If schema changes, update saved payloads

## Payload patterns

### Pattern 1: Simple request

```json
{
  "input": "string to process"
}
```

**Use case:** Single-purpose operations (text summarization, translation)

### Pattern 2: User + action + data

```json
{
  "user_id": "123",
  "action": "create",
  "data": {
    "name": "New Item",
    "description": "Item details"
  }
}
```

**Use case:** CRUD operations, user-specific actions

### Pattern 3: Batch processing

```json
{
  "items": [
    {"id": "1", "value": "A"},
    {"id": "2", "value": "B"},
    {"id": "3", "value": "C"}
  ],
  "options": {
    "parallel": true,
    "fail_fast": false
  }
}
```

**Use case:** Processing multiple items, bulk operations

### Pattern 4: Configuration-heavy

```json
{
  "data": "content to process",
  "config": {
    "format": "markdown",
    "style": "formal",
    "length": "medium",
    "audience": "technical",
    "include_citations": true
  }
}
```

**Use case:** Configurable behavior, user preferences

### Pattern 5: Streaming/chunked

```json
{
  "chunk_id": "chunk_1",
  "total_chunks": 10,
  "data": "partial data...",
  "metadata": {
    "session_id": "session_xyz"
  }
}
```

**Use case:** Large payloads split into chunks, streaming data

## Dynamic payloads

Generate payloads programmatically.

### From user input

```python
def create_payload(user_input):
    return {
        "query": user_input,
        "timestamp": datetime.now().isoformat(),
        "user_id": get_current_user_id()
    }
```

### From database

```python
def create_batch_payload(user_ids):
    users = fetch_users(user_ids)
    return {
        "users": [
            {
                "id": u.id,
                "email": u.email,
                "tier": u.tier
            }
            for u in users
        ]
    }
```

### From webhook

```python
@app.route('/webhook', methods=['POST'])
def handle_webhook():
    webhook_data = request.json
    
    payload = {
        "event_type": webhook_data['type'],
        "data": webhook_data['data'],
        "received_at": datetime.now().isoformat()
    }
    
    # Send to Triform
    execute_project(payload)
    
    return {'status': 'received'}
```

## Payload transformation

Sometimes you need to transform external data into Triform payload format.

### Example transformation

**External API response:**

```json
{
  "userId": "123",
  "fullName": "Alice Smith",
  "emailAddress": "alice@example.com",
  "accountLevel": "PREMIUM"
}
```

**Triform payload:**

```json
{
  "user_id": "123",
  "name": "Alice Smith",
  "email": "alice@example.com",
  "tier": "premium"
}
```

**Transformation code:**

```python
def transform_to_payload(api_response):
    return {
        "user_id": api_response["userId"],
        "name": api_response["fullName"],
        "email": api_response["emailAddress"],
        "tier": api_response["accountLevel"].lower()
    }
```

## Debugging payloads

### Common issues

**Problem:** Execution fails with validation error\
**Solution:** Check payload against schema, fix type mismatches or missing fields

**Problem:** Payload is valid but execution fails\
**Solution:** Check execution logs, data might be valid format but wrong content

**Problem:** Payload too large\
**Solution:** Check quotas, consider chunking or reducing data size

**Problem:** Payload works in UI but not via API\
**Solution:** Check JSON encoding, content-type header, authentication

### Testing payloads

**Step 1:** Start simple

```json
{
  "minimal_required_field": "value"
}
```

**Step 2:** Add optional fields

```json
{
  "minimal_required_field": "value",
  "optional_field": "value"
}
```

**Step 3:** Add complexity

```json
{
  "minimal_required_field": "value",
  "optional_field": "value",
  "nested_object": {
    "key": "value"
  },
  "array": [1, 2, 3]
}
```

**Step 4:** Test edge cases

```json
{
  "empty_string": "",
  "empty_array": [],
  "null_value": null,
  "large_number": 999999999
}
```

## Payload size limits

### Default limits

**Free tier:** 1 MB per payload\
**Pro tier:** 10 MB per payload\
**Enterprise:** Custom limits

### Handling large payloads

**Option 1: Chunking**
Split large payloads into smaller chunks, process sequentially

**Option 2: Reference by URL**

```json
{
  "data_url": "https://s3.amazonaws.com/bucket/large-file.json",
  "process_type": "batch"
}
```

## Next steps

Continue exploring the documentation to learn about Executions, Variables, and integrating Projects into your apps.
