Invite customers
In the Quickstart you made a link in the console and opened it yourself. In your product, your backend makes a link for whichever customer is signed in, your app sends them to it, and your backend checks when they have finished.
How it goes
Section titled “How it goes”- A customer, signed in to your app, clicks a button of yours such as Connect with Jussora.
- Your backend asks Jussora for a link, naming the customer by your own identifier for them.
- Your app sends the customer’s browser to the link.
- The customer signs in to Jussora, connects their accounts, chooses what your agent may do, and clicks Connect agent.
- A button on Jussora’s last page, Continue to followed by your agent’s name, sends them
back to the
return_urlyou gave. - Your backend asks Jussora whether calls for that customer will land. Once they will, your agent can call tools for them.
1. Make a link
Section titled “1. Make a link”Make the link when the customer asks for it, right before you send them.
curl https://app.jussora.com/v1/connection-links \ -H "Authorization: Bearer $JUSSORA_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "name": "cust_4412", "return_url": "https://example.com/settings/integrations", "refresh_url": "https://example.com/settings/integrations/jussora" }'| Field | What it is |
|---|---|
name |
Your identifier for this customer, which your agent will send in Jussora-Account. Printable ASCII with no spaces, up to 255 characters. |
return_url |
Where Jussora sends the customer when they finish, and when they cancel. |
refresh_url |
Where Jussora offers to send the customer when the link has already been used or has expired. Make it an address in your app that makes a new link and sends them on. |
Both URLs must use https. Jussora answers 422 with must be an https URL otherwise.
The answer, with 201:
{ "url": "https://app.jussora.com/connect/link/Wq_3Y46b2kKhFgyDSt-97YE_PQ_-5r41f1_z6MeKq5I", "created_at": "2026-10-17T01:17:25.752100Z", "expires_at": "2026-10-17T01:22:25.752096Z"}The link can be opened once, and expires five minutes after it is made. Making several links for the same identifier is fine. A double click, a refresh or a second visit each make a new one, and the ones nobody opens simply expire. Nothing is created for the customer until they open one.
2. Send the customer to it
Section titled “2. Send the customer to it”Here is the same request from a TypeScript server, using fetch. Call it from the route behind
your button, and from the route at your refresh_url, then redirect the customer’s browser to the
URL it returns.
// Makes a connection link for the customer signed in to your app. Call it only for that// customer, and send their browser straight to the URL it returns. Never email the link.export async function connectionLink(customerId: string): Promise<string> { const response = await fetch("https://app.jussora.com/v1/connection-links", { method: "POST", headers: { // The agent's API key stays on your server. Authorization: `Bearer ${process.env.JUSSORA_API_KEY}`, "Content-Type": "application/json", }, body: JSON.stringify({ name: customerId, return_url: "https://example.com/settings/integrations", refresh_url: "https://example.com/settings/integrations/jussora", }), }); if (!response.ok) { throw new Error(`Jussora answered ${response.status}`); } const { url } = (await response.json()) as { url: string }; return url;}The customer arrives on a Jussora page that names your agent. If they have no Jussora account yet, the same page creates one: Jussora emails them a code, or they continue with Google or Apple.
3. Know when calls will land
Section titled “3. Know when calls will land”Ask Jussora where a customer stands. Do it when they come back to your return_url, and whenever
your app needs to know. There is no webhook.
curl https://app.jussora.com/v1/connections/status \ -H "Authorization: Bearer $JUSSORA_API_KEY" \ -H "Content-Type: application/json" \ -d '{"name": "cust_4412"}'The identifier travels in the body rather than the address, so that an email address used as an identifier never lands in an access log.
{ "state": "connected", "calls_enabled": true, "requirements": [], "conflict": false}| Field | What it says |
|---|---|
state |
unknown when nobody is connected under this identifier, started when someone opened a link and has not finished, and connected once they have. |
calls_enabled |
true once the customer has accepted your agent and given it at least one tool, at Allow or Ask. |
requirements |
What is still needed, if anything. See the next table. |
conflict |
true when a link for this identifier was opened by someone other than the person connected under it. Your app showed a link to the wrong person. |
| Requirement | What it means | What to do |
|---|---|---|
accept_connection |
The customer opened a link and did not finish. | Send them to a new link. |
grant_tools |
The customer accepted your agent but gave it no tools. | Send them to a new link. Its second page is where they choose tools. |
reconnect.github |
The customer’s GitHub connection needs connecting again. The same goes for any provider. | Send them to a new link, or ask them to reconnect at app.jussora.com under Settings, then Connected accounts. |
calls_enabled stays true while a provider needs reconnecting, because other tools still work.
Calls to that provider’s tools fail until the customer reconnects.
The status never says which tools a customer chose, or how. That is theirs. When your agent calls a tool it was not given, the answer says only that the tool is not granted.
unknown is one answer for three cases: nobody ever opened a link for this identifier, the
identifier was released, or a customer declined to link it. Jussora does not tell them apart.
A customer who already uses your agent
Section titled “A customer who already uses your agent”A customer can be connected to your agent under more than one of your identifiers. If someone already connected under one identifier opens a link made for another, Jussora asks them whether to link it to the connection they have, because saying yes tells you that your two records are one person.
- If they agree, both identifiers reach the same connection, and your agent can use either.
- If they decline, Jussora writes nothing at all, and the status for the new identifier stays
unknown, as if they had never opened the link.
Give an identifier up
Section titled “Give an identifier up”When a customer leaves your app, give up your identifier for them:
curl https://app.jussora.com/v1/connections/release \ -H "Authorization: Bearer $JUSSORA_API_KEY" \ -H "Content-Type: application/json" \ -d '{"name": "cust_4412"}'The answer is {"released": true}, or {"released": false} when nothing was connected under that
identifier, which is not an error. Your agent can no longer reach the customer under that
identifier, and its status becomes unknown. Nothing in the customer’s Jussora account changes:
their connection and the tools they gave stay theirs. In the console, the agent’s page does the
same with Release name on each identifier.
A customer can also remove your agent themselves, at app.jussora.com under Settings, then Agents. Every identifier you had for them is released with it.