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

# HTTP endpoints and webhooks

> Receive requests with URL, Webhook, or Form Submission triggers and return a response.

HTTP triggers give a workflow a unique public endpoint. Choose the trigger
based on the request shape you control:

| Trigger             | Accepted request                                                     | Body and data                                               | Best for                                       |
| ------------------- | -------------------------------------------------------------------- | ----------------------------------------------------------- | ---------------------------------------------- |
| **URL**             | Common methods including `GET`, `POST`, `PUT`, `PATCH`, and `DELETE` | Text up to 10 MB; binary bodies become base64 strings       | General HTTP integrations and custom clients   |
| **Webhook**         | `POST` only                                                          | Parsed JSON up to 100 MB                                    | Services that send JSON webhooks               |
| **Form Submission** | `GET` or `POST`                                                      | Query fields on `GET`; multipart fields and files on `POST` | Browser forms, Webflow, Framer, and file forms |

Open the trigger configuration to copy its endpoint. Treat this URL like an
unguessable integration address: share it only with the systems that should
start the workflow.

## URL trigger

Use **URL** when you need control over the request method or body type. Its
trigger data includes:

* **Path**
* **Method**
* **Headers**
* **Query**
* **Body**

Header names are lowercase. Cookie, Cloudflare-prefixed, and forwarded-address
headers are omitted. Query values are exposed as strings. Text bodies remain
text; binary bodies are exposed as base64 text.

The URL shown in the trigger panel can be opened directly for a quick `GET`
test.

## Webhook trigger

Use **Webhook** for an external service that sends a JSON `POST`. Its trigger
data includes:

* **Data** — the parsed JSON value,
* **Path**,
* **Query**, and
* **Headers**.

Requests with another method receive `405 Method Not Allowed`. Invalid JSON is
rejected before the workflow receives trigger data.

## Form Submission trigger

Use **Form Submission** as an HTML form's target. A `POST` parses multipart form
fields and files. Repeated field or file names may produce lists rather than
single values.

The trigger can also serve configured HTML on `GET`. When **HTML Response** is
enabled, opening the endpoint returns that HTML and does **not** create a
workflow run. A `POST` to the same endpoint still submits the form and starts
the workflow.

If the HTML response is disabled, a `GET` starts the workflow with its query
parameters exposed as **Fields**.

## Return a custom response

Add one response action to the branch that should answer the caller. **Respond
Text**, **Respond JSON**, **Respond Status**, and **Redirect** are available for
all three HTTP triggers. The browser-oriented **Respond HTML**, **Respond
File**, and **Close Window** actions are intended for URL and Form Submission
workflows.

Connect every value that must be computed before the response. The HTTP request
waits for a response-capable action when an enabled one exists anywhere in the
run's graph snapshot.

<Warning>
  Only the first response action that executes can answer the request. If
  several response branches are eligible concurrently, their canvas position
  does not decide which wins. Make the branches mutually exclusive or route them
  into one response action.
</Warning>

## Default response behavior

The caller receives different defaults depending on the saved graph:

| Workflow outcome                                                      | HTTP result                                                                |
| --------------------------------------------------------------------- | -------------------------------------------------------------------------- |
| No enabled response-capable action exists in the run snapshot         | Immediate `202` explaining that the workflow is running without a response |
| A response action exists and runs                                     | Its configured status, headers, and body                                   |
| A response action exists, but the workflow completes without using it | `200` explaining that the workflow finished without a response             |
| The run cannot be queued or fails at the worker level                 | `400` with the workflow failure message                                    |

An action error does not automatically become an HTTP error response. A
dependent response action may be skipped because the failed action produced no
normal output, which leads to the generic completed-without-response result.
Use **Did Action Succeed?** and **Error** to build an explicit error response
branch.

See [Meta controls](/building/meta-controls) for that pattern.

## Test the endpoint

Save the graph, enable the workflow, and send a representative request. For
repeatable testing, keep an example `curl` command or request fixture with the
method, headers, query, and body your integration actually sends.

Then inspect both sides:

1. Confirm the caller received the expected status, headers, and body.
2. Open the workflow run and inspect **Data from Trigger**.
3. Check any decoded object properties, files, or base64 body before passing
   them downstream.

Follow [Testing workflows](/guides/testing-workflows) for the full edit-test
loop and [External triggers](/essentials/external-triggers) for other ways
systems can start workflows.
