Integration · Platform engineering
How to let customers connect their own accounts
A customer's connection expires on a Saturday and their sync stops without a word, and they find out from a report on Monday. How customers connect their accounts inside your product, the prompts that build it, and how to catch a broken connection before the customer does.
Built with Tray Headless
- System Your product
- Step Sign in, under your brand
- Step Check what was granted
- Step Watch every connection
- System Salesforce
The customer connects their account in your product, under your brand. A check on every connection warns them before it stops working.
The short answer
How do customers connect their own accounts to an embedded integration?
Letting customers connect their own accounts comes down to four things: a sign-in that happens inside your product and carries your name rather than an integration vendor's, a check straight after sign-in that the access granted is the access the integration needs, credentials held against that customer and never visible to your team, and a watch on every connection so an expired or revoked one is found and the customer told before their sync stops. With Tray Embedded the sign-in is the auth-only dialog or the config wizard, and a custom OAuth app plus your own domain keeps Tray's name off every screen. Most teams skip the watch. A connection that fails silently is found by the customer, a week late.
Stage 3 of 7: Customers connect their accounts. Part of Embedded integration, end to end : every stage, the systems it runs on and the guide that builds it.
What matters here
- Sign-in should carry your name. A customer asked to authorise an app they've never heard of will hesitate, and some will stop.
- Check the access granted, not just that sign-in finished. A customer who unticks a permission gets a sync that half works.
- Your team should never see a customer's credentials. They are held against the customer, and used only for their instance.
- Watch every connection. An expired token sends no error until the next run fails.
- Tell the customer in your product, with one button to reconnect. A support ticket is the slow way to fix a sign-in.
Who this is for
You build the integration experience inside a software product. Customers connect their CRM or other apps to your product, and broken connections reach you as support tickets.
How it works in practice
From the customer clicking connect to their connection still working six months later.
- 1
The customer clicks connect in your product
Your page, your button. The sign-in opens in a popup under your own domain.
- 2
They sign in to their app and approve access
The approval screen names your product, because the sign-in uses your own app registration.
- 3
The access granted is checked
Against the permissions the integration needs, with a clear message if one was left out.
- 4
The connection is stored against that customer
Usable only by their instance, never shown to your team or to other customers.
- 5
Every connection is checked on a schedule
So an expired, revoked or downgraded connection is found before a sync depends on it.
- 6
The customer is told, with one way to fix it
In your product and by email, with a reconnect button that opens the same sign-in.
What account connection is made of
Four parts. The last one is what keeps support out of the loop.
A sign-in under your brand
Your own OAuth app registration for each service, and your own domain on the sign-in popup, so no screen shows another vendor's name.
A permissions check
Straight after sign-in, a call that proves the access works for what the integration does, not just that a token came back.
Credentials held for the customer
Stored against the customer's own user, reused if they connect a second integration to the same account, and never readable by your staff.
A connection watch
A scheduled check of every customer's connections, with warnings before a sync fails and a reconnect link in the warning.
The Tray Headless prompts
Paste these into Claude Code or Codex with the Tray Headless plugin installed. Each stage runs on its own. The systems named in them are the worked example rather than a requirement, and every prompt says so.
Once per project, run
/tray-workflows:set-workspace
to pick the workspace these build in. Point it at a sandbox first.
- 1
Register your own app with each service
So the approval screen names your product.
For each service the integration connects to, starting with Salesforce, register an OAuth app under our company's developer account. Use our product name, logo and support address. Add both redirect addresses: Tray's default one, and the one on our own subdomain (ours.integration-authentication.com, or the EU equivalent). Then attach the app to the authentication in Tray Embedded so customers sign in through it. Ask only for the permissions the integration uses. A long list of scopes on the approval screen is a reason for a customer's admin to say no.
- 2
Put the sign-in in your product
Your page, your button, your domain.
Headless skills
build-workflowUse build-workflow for the backend calls. When a customer signs in to our product for the first time, create their Tray end user with our own customer id as the external id, so the two records always match. On our integrations page, open the sign-in with the auth-only dialog when the integration needs only a connection, and with the config wizard when it also needs settings. Both open on our own subdomain. If the customer already has a connection to the same account from another integration, offer it rather than asking them to sign in again.
- 3
Check what was actually granted
A sync that half works is worse than one that refuses.
Headless skills
build-workflowtray-gotchasUse build-workflow and tray-gotchas. Straight after the customer signs in, run one harmless read for each kind of record the integration uses: list one account, one contact, one opportunity. If any read is refused, tell the customer which permission is missing and offer to sign in again. Don't create the instance until every read passes. Record which user they signed in as. A connection made by a user who later leaves the customer's company is the most common reason a sync stops.
- 4
Watch every connection
An expired token sends no error until the next run fails.
Once a day, for every customer instance, check each connection with the same harmless read. On a failure, find out why: expired, revoked, the user deactivated, or a permission removed. Then: Mark the instance as needing attention in our product Email the customer's admin with what happened and one reconnect link that opens the same sign-in If nothing changes in three days, tell the account owner in Slack Never retry a sign-in on the customer's behalf, and never switch their instance to somebody else's connection.
Most broken connections trace back to the person who connected leaving the customer's company. Show the connected user on your integrations page so the customer can spot it first.
What it connects to
Your product owns the screen. The customer owns the account.
Salesforce
The customer signs in through your own app registration, approves access, and the integration reads and writes with that connection only.
Reads and writes
HubSpot
The same pattern for every OAuth service a customer connects, each with its own app registration and permission check.
Reads and writes
SendGrid
Email the customer's admin when a connection stops working, with a link to reconnect.
Writes
Same build, other stacks
The design does not change if you run something else in one of these seats. The same prompts build it against Microsoft Dynamics 365, Microsoft Teams, Marketo, Google Chat or Braze.
Connections in this build
Field mapping, templates and common problems for each pairing: HubSpot + Salesforce, SendGrid + Salesforce, SendGrid + HubSpot and Salesforce + Slack.
Named systems are the ones most teams run, not the only ones that work. Each is an authentication in your Tray workspace, referenced by name, so the workflow never holds a credential. Where we have a connector page, the name links to it.
Running it in production
This holds your customers' access to their own systems. It is the part their security team will ask about.
Credentials belong to the customer
Each connection is stored against the customer's own user and used only by their instances. Your staff never see the token.
No other vendor on the screen
Your app registration, your domain, your styling. The customer sees your product all the way through.
Broken connections are found first by you
A daily check of every connection, so the customer hears from you before their data is wrong.
Every sign-in is recorded
Who connected, when, as which user and with which permissions, so a customer's question can be answered from the record.
Questions people ask
Will customers see Tray on the sign-in screen?
Not if you register your own OAuth app with each service and use your own subdomain for the sign-in. The approval screen then names your product.
Can our support team see a customer's credentials?
No. Connections are stored against the customer's own user and used only by their instances. Support can see that a connection exists and whether it works.
What happens when a customer's connection expires?
A daily check finds it, the instance is marked as needing attention in your product, and the customer's admin gets an email with a link to reconnect. The sync stays stopped until they do.
Why check permissions after sign-in?
Because a customer can untick a permission on the approval screen, and the sign-in still succeeds. A harmless read of each record type proves the access works before anything depends on it.
Related guides
Platform engineering
How to build one integration for every customer
Build a customer-facing integration once, with every per-customer choice pulled out as a setting, so a fix ships to every customer at the same time. The prompts.
Platform engineering
How to build customer field mapping
Let each customer match your product's fields to their own, custom fields included, then turn the integration on with a first sync that doesn't flood their account. The prompts.
Platform engineering
How to build error alerts for customer integrations
Catch every failed run across every customer's integration, sort what the customer can fix from what your team must, and tell the right one first. The prompts.
Last reviewed October 2026.