Skip to main content
Core Concepts

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

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

Nested payload

{  "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

{  "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:

{  "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

TypeExampleDescription
string"hello"Text
number42, 3.14Integer or float
booleantrue, falseTrue/false
array[1, 2, 3]List of items
object{"key": "value"}Nested structure
enum"red" from ["red", "green", "blue"]Fixed options
nullnullAbsence 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:

{  "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

This is an API-call that would trigger a certain flow with the {"user_id": "123", "action": "process", "data": {"value": 42}} payload:

curl -X POST 'https://app.triform.ai/api/in/31460071-17aa-43e8-a0e6-fb22984c0bdc/26420f15-2143-443f-bca9-45c5b0720784' \  --header 'Authorization: 88ffe8398f972837ccc6e0a6cd31c5c92689040c' \  --header 'Content-Type: application/json' \  --data '{"user_id": "123", "action": "process", "data": {"value": 42}}'

Programmatically

Python:

import requestspayload = {    "user_id": "123",    "action": "process",    "data": {"value": 42}}response = requests.post(    "https://app.triform.ai/api/in/31460071-17aa-43e8-a0e6-fb22984c0bdc/26420f15-2143-443f-bca9-45c5b0720784",    headers={        "Authorization": API_KEY,        "Content-Type": "application/json"    },    json=payload)result = response.json()

JavaScript:

const payload = {  user_id: "123",  action: "process",  data: { value: 42 }};const response = await fetch(  "https://app.triform.ai/api/in/31460071-17aa-43e8-a0e6-fb22984c0bdc/26420f15-2143-443f-bca9-45c5b0720784",  {    method: "POST",    headers: {      "Authorization": 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:

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

Wrong type:

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

Invalid enum value:

{  "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:

{  "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

{  "input": "string to process"}

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

Pattern 2: User + action + data

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

Use case: CRUD operations, user-specific actions

Pattern 3: Batch processing

{  "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

{  "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

{  "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

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

From database

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

@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:

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

Triform payload:

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

Transformation code:

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 errorSolution: Check payload against schema, fix type mismatches or missing fields

Problem: Payload is valid but execution failsSolution: Check execution logs, data might be valid format but wrong content

Problem: Payload too largeSolution: Check quotas, consider chunking or reducing data size

Problem: Payload works in UI but not via APISolution: Check JSON encoding, content-type header, authentication

Testing payloads

Step 1: Start simple

{  "minimal_required_field": "value"}

Step 2: Add optional fields

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

Step 3: Add complexity

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

Step 4: Test edge cases

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

Payload size limits

Default limits

Free tier: 1 MB per payloadPro tier: 10 MB per payloadEnterprise: Custom limits

Handling large payloads

Option 1: ChunkingSplit large payloads into smaller chunks, process sequentially

Option 2: Reference by URL

{  "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.

Was this helpful?

Still need help? Ask the team