Skip to main content

Triggers API

This API enables you to execute Pinkfish workflows that you’ve created and published. With these “trigger” endpoints, you can integrate automated workflows into your applications and systems. You can also trigger one workflow from another workflow - thereby chaining workflows together.

Key Concepts

  • Workflow: A series of steps that perform a specific task or workflow.
  • Trigger: A mechanism to initiate a workflow via API call. You must set up a trigger in order to call your workflow by API.
  • Run: An instance of a workflow being executed.

Execution Models

Our API supports two execution models:

Asynchronous (Fire and Forget)

When you create a trigger for your workflow, you get two options:
  1. API Trigger Endpoint: Use this with the API key in the header (X-API-KEY)
    • Format: https://triggers.app.pinkfish.ai/ext/triggers/{triggerId}
    • Requires API key in request headers
    • Best for server-to-server integrations
  2. Webhook URL: Use this for 3rd party services that can’t set custom headers
    • Format: https://triggers.app.pinkfish.ai/ext/webhook/{apiKey}/triggers/{triggerId}
    • API key is embedded in the URL path for authentication
    • Best for services like Slack, Discord, Linear, Zoom, and other webhook-based integrations
Both options:
  • Return immediately with a runId in the response header
  • Run the workflow asynchronously in the background
  • Don’t return results directly via the API call
  • Are best for long-running workflows or when immediate response isn’t required

Synchronous (Wait for Result)

  • When you call a workflow trigger with x-api-wait: true, the API waits for up to 60 seconds for completion
  • If the workflow completes within this window, the response body contains the results
  • If the workflow takes longer than 60 seconds, the call returns with a timeout and a runId
  • Best for quick workflows where you need immediate results
To view the outcome of a workflow run (especially for async calls or timeouts), you have several options:
  1. Poll for results programmatically (recommended for integrations). See the Polling for Results section below.
  2. Check the effects of the workflow (e.g., a created Google Doc or message to Slack). This is entirely up to you to devise.
  3. Load the workflow in the platform UI (you will see results from the last run). Warning: if you have edited your workflow since your last publish, you won’t see results here.
  4. Use the Runs Monitor in the platform to view execution status and results. This is the most reliable and simple method.

Polling for Results

When you trigger a workflow asynchronously, the response includes two important headers:
  • X-Pf-Run-Id: The unique identifier for this workflow run
  • X-Pf-Automation-Id: The automation/workflow ID
You can use these values to poll for the run status and retrieve results once the workflow completes. Note: Polling endpoints use the webhook-style URL format (/ext/webhook/{apiKey}/...) even if the run was started using the API trigger endpoint with X-API-KEY header authentication.

Check Run Status

Poll the status endpoint to check if the workflow has completed:
GET https://triggers.app.pinkfish.ai/ext/webhook/{apiKey}/runs/{automationId}/{runId}/status
Response: The status endpoint returns a RunStatus object:
{
  "automationId": "csrtvshm36rc711dhoqg",
  "runId": "1731715310692281375",
  "status": "RUNNING",
  "stepStatus": {
    "1": "COMPLETE",
    "2": "RUNNING"
  },
  "stepInfo": {
    "1": {
      "status": "COMPLETE",
      "name": "Step 1",
      "executionOrder": 1
    },
    "2": {
      "status": "RUNNING",
      "name": "Step 2",
      "executionOrder": 2
    }
  }
}
Status values:
  • PENDING: Workflow is queued but not yet started
  • RUNNING: Workflow is currently executing
  • COMPLETE: Workflow completed successfully
  • FAILED: Workflow failed with an error
  • TIMEOUT: Workflow exceeded execution time limit

Get Run Results

Once the status is COMPLETE, retrieve the full results:
GET https://triggers.app.pinkfish.ai/ext/webhook/{apiKey}/runs/{automationId}/{runId}/results
Response: Returns the complete run object with all step results (same format as synchronous response):
{
  "automationId": "csrtvshm36rc711dhoqg",
  "automationVersion": 1,
  "automationName": "Hello Triggers",
  "id": "1731715310692281375",
  "type": "TRIGGER",
  "results": [
    {
      "stepIndex": 1,
      "stepVersion": 2,
      "result": {
        "stepIndex": 1,
        "resultType": "markdown",
        "result": "# Hello from step 1! 👋"
      },
      "exitCode": 0,
      "duration": 790
    }
  ],
  "started": "2024-11-16T00:01:50Z",
  "startedBy": "588233679836"
}

Using Designated Output with Async Polling

If your trigger has a designated output configured, the async results response includes a top-level designatedOutput object. Important behavior:
  • The results endpoint still returns the full run payload
  • designatedOutput is added as an extra field when it can be resolved
  • There is no query parameter to return only designated output
Example response shape with designated output:
{
  "id": "1773184744204578408",
  "status": "COMPLETE",
  "results": [
    {
      "stepIndex": 1,
      "resultUrls": {
        "poem.txt": {
          "url": "https://run-files.app.pinkfish.ai/..."
        }
      }
    },
    {
      "stepIndex": 2,
      "resultUrls": {
        "retrieved-poem.txt": {
          "url": "https://run-files.app.pinkfish.ai/..."
        }
      }
    }
  ],
  "designatedOutput": {
    "url": "https://run-files.app.pinkfish.ai/...",
    "fileName": "retrieved-poem.txt",
    "mimeType": "text/plain",
    "size": 117
  }
}
Client-side filtering example:
RESULTS=$(curl -s "https://triggers.app.pinkfish.ai/ext/webhook/YOUR_API_KEY/runs/$AUTOMATION_ID/$RUN_ID/results")

# If designatedOutput exists, use it directly
echo "$RESULTS" | jq '.designatedOutput // "No designated output found"'

# Download designated output content
DESIGNATED_URL=$(echo "$RESULTS" | jq -r '.designatedOutput.url // empty')
if [ -n "$DESIGNATED_URL" ]; then
  curl -s "$DESIGNATED_URL"
fi

Polling Example

Here’s a complete example showing how to trigger a workflow asynchronously and poll for results:
# Step 1: Trigger the workflow asynchronously
RESPONSE=$(curl -s -i --location 'https://triggers.app.pinkfish.ai/ext/triggers/YOUR_TRIGGER_ID' \
  --header 'Content-Type: application/json' \
  --header 'X-API-KEY: YOUR_API_KEY' \
  --header 'x-api-wait: false' \
  --data '{"user_request": "process this data"}')

# Step 2: Extract runId and automationId from response headers
RUN_ID=$(echo "$RESPONSE" | grep -i "X-Pf-Run-Id" | cut -d' ' -f2 | tr -d '\r')
AUTOMATION_ID=$(echo "$RESPONSE" | grep -i "X-Pf-Automation-Id" | cut -d' ' -f2 | tr -d '\r')

# Step 3: Poll for status (check every 2-5 seconds)
while true; do
  STATUS_RESPONSE=$(curl -s "https://triggers.app.pinkfish.ai/ext/webhook/YOUR_API_KEY/runs/$AUTOMATION_ID/$RUN_ID/status")
  STATUS=$(echo "$STATUS_RESPONSE" | jq -r '.status')
  
  if [ "$STATUS" = "COMPLETE" ]; then
    echo "Workflow completed!"
    break
  elif [ "$STATUS" = "FAILED" ] || [ "$STATUS" = "TIMEOUT" ]; then
    echo "Workflow failed with status: $STATUS"
    exit 1
  fi
  
  echo "Status: $STATUS, waiting..."
  sleep 3
done

# Step 4: Get the results
RESULTS=$(curl -s "https://triggers.app.pinkfish.ai/ext/webhook/YOUR_API_KEY/runs/$AUTOMATION_ID/$RUN_ID/results")
echo "$RESULTS" | jq '.'
Polling best practices:
  • Poll every 2-5 seconds for most workflows
  • For very long-running workflows, you may want to poll less frequently (every 10-30 seconds)
  • Set a maximum polling duration to avoid infinite loops
  • Handle FAILED and TIMEOUT statuses appropriately in your code

Authentication

All trigger API endpoints are authenticated using API keys.
  • API trigger endpoint (/ext/triggers/{triggerId}): include the API key in the X-API-KEY header
  • Webhook endpoint and polling endpoints (/ext/webhook/{apiKey}/...): API key is embedded in the URL path
For header-based authentication:
X-API-KEY: YOUR_API_KEY_HERE
You can generate API keys in two ways:
  1. In the Library section of the platform interface.
  2. While setting up a trigger for a workflow.

Triggering Workflows

Workflows are executed by calling their associated triggers. Each trigger has a unique endpoint and may accept parameters either as query parameters (for GET requests), as form-encoded data, as a json payload, or as multipart/form-data (with file attachments). Set up your trigger(s) in the Workflow editor (requires first publishing a version of your workflow)

Supported Content Types

API triggers support the following content types:
  • application/json: JSON payload with structured data
  • application/x-www-form-urlencoded: Form-encoded data (key-value pairs)
  • multipart/form-data: Form data with file attachments (API triggers only)
Note: Webhook triggers support JSON and form-encoded data only. File attachments are not supported for webhook triggers.

Example Requests

Asynchronous Request (Form-encoded)

curl --location 'https://triggers.app.pinkfish.ai/ext/triggers/YOUR_TRIGGER_ID' \
--header 'Content-Type: application/x-www-form-urlencoded' \
--header 'X-API-KEY: YOUR_API_KEY' \
--header 'x-api-wait: false' \
--data-urlencode 'Hello=World'

Synchronous Request (JSON)

curl --location 'https://triggers.app.pinkfish.ai/ext/triggers/YOUR_TRIGGER_ID' \
--header 'Content-Type: application/json' \
--header 'X-API-KEY: YOUR_API_KEY' \
--header 'x-api-wait: true' \
--data '{
    "user_request": "what is the capital of France"
}'

Request with File Attachments (Multipart)

API triggers support file attachments using multipart/form-data. Attachments are stored in S3 and made available to your workflow via signed URLs in the inputs. Limits:
  • Maximum 25MB per file
  • Maximum 100MB total across all attachments
  • Maximum 20 files per request
  • Executable files and scripts are blocked for security
Example with single file:
curl --location 'https://triggers.app.pinkfish.ai/ext/triggers/YOUR_TRIGGER_ID' \
--header 'X-API-KEY: YOUR_API_KEY' \
--form 'description="Process this document"' \
--form 'file=@"/path/to/document.pdf"'
Example with multiple files:
curl --location 'https://triggers.app.pinkfish.ai/ext/triggers/YOUR_TRIGGER_ID' \
--header 'X-API-KEY: YOUR_API_KEY' \
--form 'action="process"' \
--form 'files=@"/path/to/file1.pdf"' \
--form 'files=@"/path/to/file2.jpg"' \
--form 'metadata="{\"priority\": \"high\"}"'
Accessing attachments in your workflow: Attachments are available in your workflow inputs as an array. Each attachment includes:
  • filename: The sanitized filename (path components removed, special characters sanitized)
  • contentType: The MIME type of the file
  • size: File size in bytes
  • url: A signed URL to download the file from S3 (valid for 24 hours)
Example inputs structure:
{
  "description": "Process this document",
  "attachments": [
    {
      "filename": "document.pdf",
      "contentType": "application/pdf",
      "size": 245678,
      "url": "https://s3.amazonaws.com/..."
    }
  ]
}
Note: File attachments are only supported for API triggers (not webhook triggers). Webhook triggers continue to support JSON and form-encoded data only.

Example Responses

Asynchronous Response

The response body will be null. You can find your runId in the header as X-Pf-Run-Id.
Response Headers
Date: Wed, 18 Sep 2024 02:12:39 GMT
Content-Type: application/json
Content-Length: 0
Connection: keep-alive
x-amzn-RequestId: eea7315a-f8c2-4c55-88df-50f8332bf25e
Access-Control-Allow-Origin: *
Access-Control-Allow-Headers: Content-Type, Authorization
X-Pf-Automation-Id: crkbpb5b9nas7163a4kg
x-amz-apigw-id: eR2LpEkBPHcEK9w=
Access-Control-Allow-Methods: GET, POST, PUT, DELETE, OPTIONS
X-Amzn-Trace-Id: Root=1-66ea3717-03397efa60d2632525a8fe5f
X-Pf-Run-Id: 1726625559774364090
Response Body
null

Synchronous Response (Successful)

If the workflow completes within 60 seconds, you’ll receive the results in the response body:
{
    "automationId": "csrtvshm36rc711dhoqg",
    "automationVersion": 1,
    "automationName": "Hello Triggers",
    "id": "1731715310692281375",
    "type": "TRIGGER",
    "stepMap": {
        "1": 2,
        "2": 2
    },
    "inputs": "",
    "triggerId": "csru0bg3tgfs71020ssg",
    "results": [
        {
            "stepIndex": 1,
            "stepVersion": 2,
            "result": {
                "stepIndex": 1,
                "resultType": "markdown",
                "result": "# Hello from step 1! 👋"
            },
            "exitCode": 0,
            "duration": 790
        },
        {
            "stepIndex": 2,
            "stepVersion": 2,
            "result": {
                "stepIndex": 2,
                "resultType": "plaintext",
                "result": "Hello from step 2!"
            },
            "exitCode": 0,
            "duration": 707
        }
    ],
    "started": "2024-11-16T00:01:50Z",
    "startedBy": "588233679836"
}

Synchronous Response (Timeout)

If the workflow doesn’t complete within 60 seconds:
Response Headers
[same as async response]

Response Body
{
    "status": "timeout",
    "message": "Workflow execution exceeded 60 second timeout. Use runId to check results in Run Monitor."
}

Webhook Triggers

Webhook triggers provide an alternative way to execute workflows when working with third-party services that cannot set custom headers (like Slack, Discord, Linear, Zoom, etc.). Note: Webhook triggers support JSON and form-encoded data only. File attachments (multipart/form-data) are not supported for webhook triggers. Use API triggers if you need to send file attachments.

Webhook URL Format

https://triggers.app.pinkfish.ai/ext/webhook/{apiKey}/triggers/{triggerId}

Key Differences from API Triggers

FeatureAPI TriggerWebhook Trigger
AuthenticationAPI key in X-API-KEY headerAPI key embedded in URL path
URL Format/ext/triggers/{triggerId}/ext/webhook/{apiKey}/triggers/{triggerId}
Content TypesJSON, form-encoded, multipartJSON, form-encoded only
File Attachments✅ Supported (multipart)❌ Not supported
Use CaseServer-to-server integrationsThird-party services with webhook support
SecurityMore secure (key in headers)Less secure (key visible in URL)

Example Webhook Request

POST https://triggers.app.pinkfish.ai/ext/webhook/L2wOL4e7yr6G3Us5LKqHa1BLuhMIW5iR1vAqwFga/triggers/d1a49cl8hlvc714q38e0
Content-Type: application/json

{
    "event": "issue_created",
    "issue_id": "12345",
    "title": "New feature request"
}

Security Considerations

Since the API key is embedded in the webhook URL:
  • Treat webhook URLs as sensitive credentials
  • Only share with trusted third-party services
  • Consider rotating API keys periodically
  • Monitor webhook usage in the Runs Monitor

Common Webhook Integrations

  • Slack: Use in Slack workflows or slash commands
  • Discord: Set up bot commands or server events
  • Linear: Trigger workflows on issue updates
  • Zoom: Execute workflows from Zoom apps
  • GitHub: Run workflows on repository events
  • Stripe: Process payment events

Getting Started

To begin using the AI Workflow API, you’ll need to:
  1. Create and publish a workflow using our platform.
  2. Set up a trigger for your workflow.
  3. Generate an API key from either the Library section or during trigger setup.
  4. Choose your execution model (sync or async) based on your workflow’s expected runtime and your application’s needs.
  5. Use the provided trigger endpoint to execute your workflow, including your API key and preferred wait setting in the request headers.