Trigger blueprints via API - Writer AI Studio

API Trigger

The API Trigger block enables external systems to trigger your blueprint via HTTP API calls. Use it to integrate your agent with webhooks, external services, or other applications that need to programmatically execute your workflows. Unlike the UI Trigger block that responds to user interactions in the interface, the API Trigger block accepts HTTP POST requests to trigger blueprint execution.

You must deploy your agent before you can trigger a blueprint via API.

Overview

When you add an API Trigger block to your blueprint, it creates a public HTTP endpoint that external systems can use to trigger your blueprint execution. This enables:

How it works

The API Trigger block creates an HTTP endpoint that external systems can use to trigger your blueprint.

Here’s what happens when you add an API Trigger block:

Endpoint creation

The block creates two HTTP endpoints using your agent and blueprint IDs:

Request handling

When an external system calls your endpoint:

Accessing the payload data

@{result} is only available in the block that immediately follows the API Trigger block. For subsequent blocks, you have two options to access the payload data:

  1. Use a Set State block: Make the first block after API Trigger a Set State block to store the payload data for use throughout your blueprint
  2. Access via block ID: Use @{results.[api_trigger_block_id]} where [api_trigger_block_id] is the unique identifier found in the API Trigger block’s configuration menu

Return values

To send data back to the API caller:

Blueprint structure requirements

When building blueprints that will be triggered via API, ensure your workflow ends with a Return Value block:

  1. Start with API Trigger: Begin your blueprint with the API Trigger block
  2. Process your logic: Add all the blocks needed for your workflow
  3. End with Return Value: Always finish with a Return Value block to specify what gets returned to the API caller

Example blueprint structure:

API Trigger → [Your workflow blocks] → Return Value

The Return Value block returns any value as a string. If your blueprint returns a JSON object, it will be serialized as a JSON string. You may need to parse it using JSON.parse() in JavaScript or json.loads() in Python to access the individual fields.

API endpoint

When you add an API Trigger block to your blueprint, it creates a public HTTP endpoint that you can use to trigger your blueprint. You can either use the synchronous endpoint for real-time execution and to get the result as soon as possible, or the asynchronous endpoint for long-running tasks. The asynchronous endpoint returns a job ID that you can poll for status updates and results.

Authentication

All API calls require authentication using a Bearer token in the Authorization header:

Authorization: Bearer <your_api_key>

Learn how to create and manage API keys.

Synchronous endpoint

The endpoint URL follows this pattern:

POST https://api.writer.com/v1/agents/{agent_id}/blueprints/{blueprint_id}

Where:

The synchronous endpoint is used for real-time execution. It accepts a JSON payload and returns Server-Sent Events (SSE) with real-time execution status.

Request format

Send a POST request with a JSON body containing the data you want to pass to your blueprint.

The inputs key is required for the JSON payload. If you don’t include it, the API will return an error. Include the rest of your data under the inputs key. The value of the inputs key can be any JSON-serializable value.

cURL example

curl -X POST "https://api.writer.com/v1/agents/123e4567-e89b-12d3-a456-426614174000/blueprints/ooamr04yng7" \
  -H "Authorization: Bearer <your_api_key>" \
  -H "Content-Type: application/json" \
  -d '{"inputs": {"document_id": "doc_67890", "file_url": "https://storage.example.com/documents/invoice_2024_001.pdf", "document_type": "invoice", "priority": "high"}}'

Python example

import os
import requests

response = requests.post(
    "https://api.writer.com/v1/agents/123e4567-e89b-12d3-a456-426614174000/blueprints/ooamr04yng7",
    headers={"Authorization": f"Bearer {os.environ.get('WRITER_API_KEY')}"},
    json={"inputs": {"document_id": "doc_67890", "file_url": "https://storage.example.com/documents/invoice_2024_001.pdf", "document_type": "invoice", "priority": "high"}},
    stream=True
)

for line in response.iter_lines():
    if line:
        line = line.decode('utf-8')
        if line.startswith('data: '):
            data = line[6:]
            if data == '[DONE]':
                break
            print(f"Received: {data}")

JavaScript example

import fetch from 'node-fetch';

const response = await fetch(
    "https://api.writer.com/v1/agents/123e4567-e89b-12d3-a456-426614174000/blueprints/ooamr04yng7",
    {
        method: 'POST',
        headers: {
            'Authorization': `Bearer ${process.env.WRITER_API_KEY}`,
            'Content-Type': 'application/json'
        },
        body: JSON.stringify({
            inputs: { document_id: "doc_67890", file_url: "https://storage.example.com/documents/invoice_2024_001.pdf", document_type: "invoice", priority: "high" }
        })
    }
);

const reader = response.body.getReader();
const decoder = new TextDecoder();

while (true) {
    const { done, value } = await reader.read();
    if (done) break;

const chunk = decoder.decode(value);
    const lines = chunk.split('\n');

for (const line of lines) {
        if (line.startsWith('data: ')) {
            const data = line.slice(6);
            if (data === '[DONE]') {
                return;
            }
            console.log('Received:', data);
        }
    }
}

Response format

The API returns Server-Sent Events (SSE) with real-time execution status:

data: {"status":"in progress","message":null}
data: {"status":"initializing","message":"Initializing session..."}
data: {"status":"validating","message":"Validating blueprint..."}
data: {"status":"executing","message":"Executing blueprint: ooamr04yng7..."}
data: {"status":"running","message":"Blueprint is running. Awaiting output..."}
data: {"status":"processing","message":"Processing blueprint result..."}
data: {"delta":"Document processed and routed to accounting team"}
data: [DONE]

Asynchronous execution

For long-running workflows, you can also use the asynchronous endpoint:

POST https://api.writer.com/v1/agents/{agent_id}/blueprints/{blueprint_id}/jobs

This returns a job ID that you can poll for status updates using:

GET https://api.writer.com/v1/agents/jobs/{job_id}

Example job result

When you poll the job status, you’ll receive a response like this:

{
  "job_id": "6f6919ba-d97f-4315-bddf-191e5c3efb89",
  "agent_id": "5d746de9-73e7-4c0e-b264-a514f672a3f9",
  "blueprint_id": "ooamr04yng7",
  "status": "completed",
  "artifact": "Document processed and routed to accounting team",
  "error": null,
  "started_at": "2025-08-14T22:26:06.259540Z",
  "finished_at": "2025-08-14T22:26:06.700431Z"
}

The actual return value from your agent is in the artifact field of the JSON response. The result field contains metadata about the job execution. The artifact field always contains a string. If your blueprint returns a JSON object, it will be serialized as a JSON string. You may need to parse it using JSON.parse() in JavaScript or json.loads() in Python to access the individual fields.

Creating and polling async jobs

Here is an example of how to create an async job and then poll for results:

cURL

# 1. Create the async job
curl -X POST "https://api.writer.com/v1/agents/123e4567-e89b-12d3-a456-426614174000/blueprints/ooamr04yng7/jobs" \
  -H "Authorization: Bearer <your_api_key>" \
  -H "Content-Type: application/json" \
  -d '{"inputs": {"document_id": "doc_67890", "file_url": "https://storage.example.com/documents/invoice_2024_001.pdf", "document_type": "invoice", "priority": "high"}}'

# Response: {"job_id": "job_abc123def456", "status": "queued"}

# 2. Poll for job status and result
curl -X GET "https://api.writer.com/v1/agents/jobs/job_abc123def456" \
  -H "Authorization: Bearer <your_api_key>"

Python example

import os
import requests
import time

def create_and_poll_job(agent_id, blueprint_id, inputs):
    url = f"https://api.writer.com/v1/agents/{agent_id}/blueprints/{blueprint_id}/jobs"
    headers = {
        'Authorization': f"Bearer {os.environ.get('WRITER_API_KEY')}",
        'Content-Type': 'application/json'
    }

response = requests.post(url, headers=headers, json={'inputs': inputs})
    job_data = response.json()
    job_id = job_data['job_id']

print(f"Job created: {job_id}")

while True:
        poll_url = f"https://api.writer.com/v1/agents/jobs/{job_id}"
        poll_response = requests.get(poll_url, headers=headers)
        job_status = poll_response.json()

print(f"Job status: {job_status['status']}")

if job_status['status'] in ['completed', 'error']:
            return job_status

time.sleep(2)

result = create_and_poll_job(
    '123e4567-e89b-12d3-a456-426614174000',
    'ooamr04yng7',
    {'document_id': 'doc_67890', 'file_url': 'https://storage.example.com/documents/invoice_2024_001.pdf', 'document_type': 'invoice', 'priority': 'high'}
)
print(f"Final result: {result}")
print(f"Artifact: {result['artifact']}")

JavaScript example

import fetch from 'node-fetch';

async function createAndPollJob(agentId, blueprintId, inputs) {
    const createResponse = await fetch(
        `https://api.writer.com/v1/agents/${agentId}/blueprints/${blueprintId}/jobs`,
        {
            method: 'POST',
            headers: {
                'Authorization': `Bearer ${process.env.WRITER_API_KEY}`,
                'Content-Type': 'application/json',
            },
            body: JSON.stringify({ inputs }),
        }
    );

const jobData = await createResponse.json();
    const jobId = jobData.job_id;

console.log(`Job created: ${jobId}`);

while (true) {
        const pollResponse = await fetch(
            `https://api.writer.com/v1/agents/jobs/${jobId}`,
            {
                headers: {
                    'Authorization': `Bearer ${process.env.WRITER_API_KEY}`,
                },
            }
        );

const jobStatus = await pollResponse.json();
        console.log(`Job status: ${jobStatus.status}`);

if (jobStatus.status === 'completed' || jobStatus.status === 'error') {
            return jobStatus;
        }

await new Promise(resolve => setTimeout(resolve, 2000));
    }
}

createAndPollJob(
    '123e4567-e89b-12d3-a456-426614174000',
    'ooamr04yng7',
    { document_id: 'doc_67890', file_url: 'https://storage.example.com/documents/invoice_2024_001.pdf', document_type: 'invoice', priority: 'high' }
).then(result => {
    console.log('Final result:', result);
    console.log('Artifact:', result.artifact);
});

List available agents and blueprints

To see a list of all your agents and blueprints, you can use the following API endpoint:

GET https://api.writer.com/v1/agents?type=builder

This returns a list of all your deployed Agent Builder agents and includes any API-triggered blueprints associated with them.

cURL example

curl -X GET "https://api.writer.com/v1/agents?type=builder" \
  -H "Authorization: Bearer <your_api_key>"

Python example

import os
import requests

response = requests.get(
    "https://api.writer.com/v1/agents?type=builder",
    headers={"Authorization": f"Bearer {os.environ.get('WRITER_API_KEY')}"}
)

print(response.json())

JavaScript example

import fetch from 'node-fetch';

const response = await fetch(
    "https://api.writer.com/v1/agents?type=builder",
    { headers: { Authorization: `Bearer ${process.env.WRITER_API_KEY}` } }
);

console.log(await response.json());

Testing

You can test your API trigger using the Run blueprint button in the Agent Builder editor. Under Test your trigger in the API Trigger block, you can provide sample data for testing without making actual HTTP requests.

Troubleshooting

Common issues and solutions

I can’t see or trigger my agent via the API

Problem: Your agent doesn’t appear in the API or you get errors when trying to trigger it. Solution: Check that your agent is deployed. Only deployed agents are accessible via the API.

I don’t see my blueprint when looking via the API

Problem: Your blueprint doesn’t show up in the list of available blueprints for your agent. Solution: Ensure your blueprint starts with an API Trigger block. Only blueprints that begin with an API Trigger block are exposed via the API.

The blueprint isn’t returning anything

Problem: Your blueprint executes but doesn’t return any data to the API caller. Solution: Make sure you have a Return Value block at the end of your blueprint workflow. This block is required to return data to the API caller.

My blueprint isn’t receiving any input values

Problem: You can’t access the data you sent in your API request. Solution: Remember that your data is nested under the inputs key. Use @{result.inputs.field_name} instead of @{result.field_name}.

Debugging tips

Since there are limited logs and execution visibility, use the Return Value block for debugging:

Next steps