How it works
Credentials go directly from the user to your server over HTTPS. Your server opens the connection with Deck. Deck handles everything from there.Connection states
A connection moves through a defined set of states. Your UI should map to each one.| Status | What to show |
|---|---|
connecting | Loading indicator. “Connecting to {source name}…” |
interaction_required | MFA or verification form built from the interaction.fields array |
connected | Success confirmation. The connection is ready for task runs. |
disconnected | Error message with option to retry |
terminated | Connection was intentionally ended |
Step-by-step implementation
Build a credential form
Start with a form that collects the credentials required by the source. Most sources use
username_password, but Deck also supports google_sso and none for sources that don’t require credentials.Open the connection server-side
Your server receives the credentials and opens a connection with Deck. This can be an Express handler, a Next.js API route, or any server-side endpoint.The response comes back immediately with
status: "connecting". Deck is now authenticating in the background.Listen for events
Deck sends events to your event destination as the connection progresses. Use them to relay state changes to your frontend.Use WebSockets, server-sent events, or polling to push state changes to your client. The
external_id on the connection maps back to the user in your system.Handle MFA and interactions
When Deck encounters MFA, security questions, or other verification prompts, it pauses and sends an
Build your form dynamically from the Your server forwards the response to Deck:Deck resumes where it left off. If authentication succeeds, Deck sends a
interaction_required event. The event payload tells you exactly what to ask the user.The interaction object contains:| Field | Description |
|---|---|
type | The kind of challenge: mfa, security_question, account_selection |
message | A human-readable prompt from the source, e.g. “Enter the 6-digit code sent to your phone” |
fields | An array of inputs to collect, each with name, type, and label |
fields array so it adapts to whatever the source requires:connection.connected event. If the source requires another round of verification, you get another interaction_required event. Your UI handles it the same way.Handling errors
Build your UI to handle common failure cases gracefully:| Scenario | What happened | Recommended UX |
|---|---|---|
| Invalid credentials | Source rejected the username/password | Show an error on the form. Let the user retry. |
| MFA timeout | User took too long to enter a code | Explain the timeout. Offer to restart the connection. |
| Source unavailable | The target website is down or blocking | Show a temporary error. Suggest trying again later. |
| Connection disconnected | Session expired between task runs | Prompt the user to reconnect. Deck will re-authenticate using stored credentials if available. |
UX recommendations
- Show the source name and logo in your credential form so users know where they’re connecting
- Use the
interaction.messagedirectly as your form label. It comes from the source and is specific to the prompt. - Add a timeout indicator during MFA so users know they have limited time to respond
- Store the
connection_idandexternal_idmapping so you can look up connections by your own user IDs - Consider a “Connected accounts” settings page where users can see active connections, disconnect, and reconnect
