# Connectors and Extensibility

From [Descope Fundamentals](https://learn.descope.io/c/foundations) — Learn the platform by configuring your own project — every module ends in work the app checks for real.

Take this course interactively at https://learn.descope.io/c/foundations/connectors-and-extensibility

---

![Audit and Troubleshooting Connectors. 2 minutes.](video:connectors-and-extensibility-audit-and-troubleshooting-connectors)

## Two independent streams

- Stream Audit Events — security- and compliance-relevant records: a role removed from a user, a flow modified in production, a project setting changed.
- Stream Troubleshooting Events — the same detail as Descope's Troubleshooting Logs: flow execution errors, and for connector actions the complete request and response exchanged.

> [!WARNING]
> The two toggles are independent, and checking one does not turn on the other. When a security engineer reports that audit events are missing from Datadog, the first thing to check is whether Stream Audit Events was ever enabled — it is easy to turn a connector on for troubleshooting and assume audit data comes along for free.

Enabling external streaming removes nothing from Descope's own Console views; audit and troubleshooting data still appears there too. And because these connectors never run inside a flow, they have no Context Key setting — there is no flow context to write into. If a customer's SIEM is not among the named connectors, the fallback is the Audit Webhook Connector, whose optional HMAC Secret lets the receiving API verify the request genuinely came from Descope.

## Key terms

- Stream Audit Events — forwards security- and compliance-relevant records to an external tool.
- Stream Troubleshooting Events — forwards flow execution errors and full connector request/response detail.
- Audit Webhook Connector — the fallback for a SIEM Descope does not name directly.

![Audit and Troubleshoot, which is three logs behind one set of tabs: Audit for what users and admins did, Troubleshooting for why a flow failed, Flow Activity for a per-step trace of one run. The Audit list here is filtered to the last 24 hours and mixes `LoginFailed` warnings with `FlowCreated` and `FlowUpdated` information events. The link at the top is how the same events get streamed to your own logging system.](connectors-and-extensibility-audit-and-troubleshooting-connectors)

## Summary

- That the two streams are independent toggles, and the support call that follows from forgetting it
- That Console views keep everything regardless of what is streamed elsewhere
- Why these connectors have no Context Key
- What to reach for when the customer's tool is not on the list

---

![Connector Fundamentals. 2 minutes.](video:connectors-and-extensibility-connector-fundamentals)

A flow on its own only knows what Descope knows. Connectors are how it reaches everything else — third-party services, customer backends, private networks, security tools. A connector is like a saved contact: configure the base URL, auth, and headers once, then any flow that needs it drops in a connector step and fills in only what changes.

Configuration happens once, on the Connectors page in the Console, not inside the flow. That separation is deliberate: credentials and connection details live in one place, and any flow author can reuse the connector without ever seeing the underlying secrets. Most connectors offer a Test button that sends a real request and shows the result, worth using before wiring one into a live flow.

Once configured, add it to a flow from the editor with the + icon and select Connector. Each step has its own settings, independent of the connector's base configuration. Connectors run synchronously by default: the flow pauses, waits for the response, and only then continues. You can mark a step to run asynchronously for cases where the flow genuinely does not need to wait — firing an analytics event or a Slack notification are the classic examples.

> [!WARNING]
> An async step never writes its response to flow context, whether or not the call succeeded. A later condition reading connectors.analytics.status will find nothing there — which is the usual explanation when a connector "worked" but nothing downstream can see it.

The response of a synchronous step lands in flow context under its Context Key. A connector with context key userLookup returning a nested user object is referenced by the full path — connectors.userLookup.user.profile.role. That result can feed more than a condition: the Custom Claims action and the Update User Properties action both consume connector output too.

## Key terms

- Connector — a saved, reusable configuration (base URL, auth, headers) a flow step can call without exposing secrets.
- Context Key — the name a step's response is stored under in flow context.
- Async step — a step marked to run without pausing the flow; its response is never written to flow context.

![The Connectors page, with the connectors this project has configured at the top and the template catalog below. The filters across the middle — Flows, Audit, Messaging, External Token, Chat, Risk, Fraud — are the categories of work a connector does, and the tags on each card tell you where it can be used. Generic HTTP is the fallback for any service with no template of its own.](connectors-and-extensibility-connector-fundamentals)

## Summary

- That configuration and usage are cleanly separated, and why
- When to mark a step async, and what you give up by doing so
- How to reference a nested value from a connector response
- Which flow features besides conditions can consume a connector's result

---

![HTTP Connectors. 2 minutes.](video:connectors-and-extensibility-http-connectors)

Most third-party connectors are purpose-built for one service. The Generic HTTP Connector is different: a general-purpose bridge to any HTTP API, most importantly a customer's own backend. Where a purpose-built connector already knows how Slack or Twilio expects a request shaped, a Generic HTTP Connector call is one you design yourself.

Configuration starts like any connector — a name, an optional description, and a Base URL, the root of the API you are calling. Everything the flow does with it builds on that base. The base URL can itself be dynamic: including a {{value}} placeholder lets you swap in something like a region code at request time, so one connector serves multiple regions or environments rather than needing one per region.

When a backend needs to verify a request genuinely came from Descope, the HMAC Secret setting signs it. For a backend that expects a client_id and client_secret exchanged for a short-lived access token, use OAuth 2.0 Client Credentials as the authentication method.

## The four error-handling behaviors

- Automatic — redirect to the last screen with an error message.
- Mitigate — continue silently, as if the step succeeded. Useful for avoiding user enumeration.
- Continue — pass the error to a later step for explicit handling.
- Ignore — treat the step as successful regardless of outcome.

> [!WARNING]
> Descope does not automatically retry a timed-out connector call. Retries must be modeled as flow logic. And branching on an HTTP error code takes two things, not one: custom error handling enabled on the step, plus a condition reading connectors.<Context Key>.statusCode.

## Key terms

- Generic HTTP Connector — a general-purpose connector for calling any HTTP API.
- HMAC Secret — a signing credential letting a customer backend verify a request came from Descope.

![Creating a Generic HTTP connector. Base URL is the root the flow's per-call path is appended to, and Authentication Type is where the credential lives — Bearer Token, API Key, Basic, or OAuth 2.0 Client Credentials, fetched from the authorization server you name. Everything on this page is configured once, outside any flow, which is why a flow author never handles the secret.](connectors-and-extensibility-http-connectors)

## Summary

- How one connector can serve many regions through a dynamic base URL
- That there is no built-in retry, and what that implies for design
- The two things required to branch on an HTTP status code
- Which auth method fits a client_id / client_secret backend

---
