Developers: API, webhooks & n8n

API keys and scopes, catch URLs that start an automation, outgoing webhooks, and the three ways to wire up n8n.

Everything you need to connect ReflexWare to another system — n8n, Make, Zapier, or your own backend. Find it under Settings → Developers.

There are three separate things on that page, and it helps to know which one you need:

You want to…Use
Let another system read or change your dataAn API key
Let another system start a ReflexWare automationAn incoming webhook (catch URL)
Have ReflexWare tell another system when something happensAn outgoing webhook (on the Integrations tab)
Have a ReflexWare automation run one of your n8n workflowsThe n8n connection

API keys

An API key lets an outside system act as your organization.

  1. Settings → Developers → New key.
  2. Give it a name you will recognise later — "n8n production", not "test".
  3. Choose its scopes.
  4. Copy the key. It is shown once. If you lose it, rotate the key rather than trying to recover it.

Use it as a bearer token:

curl https://app.yourdomain.com/api/v1/me \
  -H "Authorization: Bearer rw_live_..."

Scopes, and one thing that surprises people

Grant only what the integration needs. A write scope does not include the matching read scope. A key with leads:write can create and update leads but cannot list them.

That is deliberate. It is what makes a key safe to paste into a third-party form or a partner's system: they can send you people, and they cannot download your database.

"Full access" grants everything, including scopes added in future releases. It is convenient while you are trying things out. Narrow it before the key leaves your hands.

Rotating and revoking

  • Rotate replaces the secret and keeps everything else — the name, the scopes, the usage history, the row you are looking at. Use it when a key may have been exposed.
  • Revoke stops the key working immediately. The row stays, marked revoked, so you can still see that "n8n production" existed and when it stopped. A key that simply vanished would turn an integration outage into a mystery.

Rate limits

Each key has its own limit (120 requests per minute by default). Every response carries X-RateLimit-Limit, X-RateLimit-Remaining, and X-RateLimit-Reset. A throttled request answers 429 with Retry-After.


Incoming webhooks — letting another system start an automation

An incoming webhook is a URL you paste into the other system. When anything posts to it, a ReflexWare automation runs.

  1. Settings → Developers → New catch URL.
  2. Name it after the thing that will call it — "n8n — deal won".
  3. Choose which automation it starts. Binding it to one automation keeps this URL from accidentally starting your other inbound integrations. Leave it on "any" only if you have a single inbound integration.
  4. Copy the URL and paste it into the other system.
  5. Send a test event from that system. ReflexWare stores the payload, and you can then see exactly which fields you have to work with.

The automation needs a Webhook Received trigger to respond.

There are also Tag Added and Tag Removed triggers, which fire when a person or an integration changes a lead's tags. Tags applied by an automation deliberately do not fire them — otherwise a workflow that tags a lead would start itself again.

Using the payload in an automation

Once a test event has arrived, reference its fields with variables:

{{trigger.webhook.payload.customer.email}}
{{trigger.webhook.payload.amount}}

Click View last payload on the catch URL to see the exact shape.

If the payload contains an email or phone we recognise

ReflexWare tries to match the payload to an existing lead. If it finds one, every lead-based step in the automation — add a tag, send an email, move a pipeline ticket — just works, with nothing extra to configure.

It will never create a lead from a webhook. If that is what you want, add an explicit step to the automation.

Accepted formats

JSON is the normal case, but a catch URL will also accept form-encoded bodies, an empty body (plenty of webhooks are pure signals), and GET requests where the query parameters become the payload. The point is to accept what the other system already sends.

Signatures

By default the URL itself is the credential — it contains 32 bytes of randomness and cannot be guessed. If the sending system can sign its requests, you can require it:

  • X-Hub-Signature-256 — the GitHub and Meta convention.
  • Standard Webhooks (svix) — what ReflexWare itself sends.

Choosing one gives you a signing secret, shown once, to paste into the sending system. Deliveries without a valid signature are then rejected with 401.


Outgoing webhooks

These live on Settings → Integrations, where they already were. Register a URL, choose which events it should receive, and ReflexWare posts to it — signed with the Standard Webhooks scheme, with every attempt recorded in a delivery log you can inspect.

Failed deliveries are retried automatically — up to five more times, backing off 1 minute, 5 minutes, 30 minutes, 2 hours, then 6 hours. That is a little over eight hours of cover, so an overnight outage on your receiver costs you nothing.

Two exceptions, both deliberate. A 4xx response (other than 408 or 429) is treated as permanent: it means the endpoint is misconfigured, and five more identical requests would tell you nothing the first one did not. And a URL blocked by the safety check is not retried either.

An event that never got through after every attempt is marked lost, and the card shows a banner with a count — you can filter to just those and press Replay to send it again. An endpoint that fails ten events in a row is disabled automatically, so a URL that has gone away does not keep generating traffic forever.


n8n

Three ways to use n8n with ReflexWare. They are not alternatives — most people end up using more than one.

1. n8n reacts to ReflexWare events

Install the n8n-nodes-reflexware community node in n8n (Settings → Community Nodes → Install), add a ReflexWare API credential using your instance URL and an API key, then drop a ReflexWare Trigger node into a workflow and pick your events.

The node registers its own webhook when you activate the workflow and removes it when you deactivate — you never paste a URL by hand, and you never leave a dead subscription behind. It needs the webhooks:manage scope to do that.

2. n8n does things in ReflexWare

Use the ReflexWare action node from the same package: get and update leads, list automations and enroll a lead into one, and read pipelines, tags, forms, conversations, and appointments.

Or skip the package and call the REST API from an HTTP Request node — the full API description is at /api/v1/openapi.json.

3. A ReflexWare automation runs an n8n workflow

Connect your instance under Settings → Developers → n8n: paste the instance URL and an n8n API key (in n8n: Settings → n8n API → Create an API key). ReflexWare tests the connection immediately and shows you the result.

Then use the Run n8n Workflow action in any automation. You pick the workflow from a live list. By default it sends everything about the run — the lead, the trigger, your organization — and you can supply your own payload instead.

If your n8n does not expose the REST run endpoint, choose "Address by webhook path" and give the path from the workflow's own Webhook trigger node.


The API itself

The complete, always-current description is served at:

https://app.yourdomain.com/api/v1/openapi.json

Point any OpenAPI tool at it to generate a client, or import it into Postman or n8n's HTTP Request node.

Every response uses the same envelope:

{ "status": "ok", "data": { }, "pagination": { } }

and every failure the same one:

{ "status": "error", "code": "FORBIDDEN", "message": "…" }

Branch on code, not on message — codes are stable, wording is not.


Troubleshooting

401 on every request. The key is wrong, revoked, or expired. Check the prefix shown in Settings against the key you are sending.

403 with a scope named. The key is valid but was not granted that scope. Edit the key's scopes, or mint a new one.

My catch URL returns 404. The URL is wrong, or the catch URL is disabled. Both answer 404 on purpose, so someone holding only the URL cannot tell a wrong address from a paused integration.

The webhook arrives but nothing happens. The automation needs a Webhook Received trigger and must be Active — a draft automation accepts nothing. If the catch URL is bound to a specific automation, only that one will run.

n8n says "connection failed". The card shows n8n's own error. A 401 means the API key is wrong; a 404 usually means the base URL has a path or trailing slash on it — it should be just the instance root.