Integration .connect
Connect an account you already own, approving only the grants its jobs need.
- Action class
- None
- Approval
- Runs on its own
- Emits
Integration.connected- Sites
- 1 sites
- Price
- Free
POST https: //api.sb/ {your-domain}/ integrations/ connect
Connects an account you already own, with only the grants its jobs need, through the site’s own sign-in. The hub’s definition of Integration.connect.
Inputs
| Name | Type | Default | Meaning |
|---|---|---|---|
system | System | Required | The System the Integration serves. |
scope | string | Required | One of studio, startup or customer; a person’s own account is startup, narrowed to them. |
grants | string[] | Required | The access requested, shown to the account holder before they approve. |
venue | string | null | The id of the ad, social or app-store venue the account is on. Unset for an account that is not on one, such as a CRM or a calendar. |
for | Party | null | The account holder, when an Agent asks on their behalf. Unset: the caller is the account holder. |
Outputs
| Field | Type | What null means |
|---|---|---|
integration | Integration | Never null. |
connectUrl | url | Never null while the Integration reads connecting. |
integration.state | string | Never null: connecting until the account holder approves, then connected. |
integration.account | string | Unknown until the account holder signs in, so always null in try mode and while connecting. |
integration.grants | string[] | Never null: the grants asked for, narrowed to what the account holder approved. |
integration.environment | string | Never null: test under a sk_test_ key, live otherwise. |
Effects
- Action class
None: no approval rule names it, so it runs within its seat’s Permissions and Limits
- Modes
try: Checks each grant against the Verbs of the System and returns the Integration it would open; nothing is stored and the link opens nothing.send: Returns theconnectingIntegration and itsconnectUrlat once;Integration.connectedfires when the account holder approves.do: Holds the call for the Mode’s hold time, then returns202with the pending Action if nobody has approved yet.
- Idempotency
Only with a key: the same
Idempotency-Keyand input return the first Action, and the same key with other input returns409. Connecting an account that already holds aconnectedIntegration for the same System returns that Integration, with any new grants added to it.- Saved or shared
The Integration records
connectedBy, the outside account and the approved grants. The token is never in a response, an Event or a log, and nothing is shared with other startups.- Emits
Integration.connectedwith{ integration,system, venue, account, grants, connectedBy } - Performed by
- Price
Free on your own account: the platform charges nothing for the call.
On each Venue
| Site | Fields | Formats |
|---|---|---|
| The CRM you already use | None. | None. |
The CRM you already use
Through The CRM you already use.
- Direction. One per Integration. Your records stay the record in both modes, and the side you declared leads every conflict.
What try does
| Account | What try does |
|---|---|
| The CRM you already use | Reads your CRM and returns what one sync would change on each side, record by record; nothing is written to either. |
Refuses when
This call has no refusals of its own. Every call through an account can also meet the shared account refusals: grant-missing, needs-reauth, account-not-connected, over-mandate, quota-reached, venue-rejected.
When it waits
| Fact | Value |
|---|---|
send returns | A pending Action, reason:, holding the connectUrl the account holder opens. |
| Delivered by | Integration.connected |
Example
Connect my cold inbox, dana@tryleaseline.app, so my agents can send from
it and read the replies.To retry, send the same Idempotency-Key: the retry returns the first answer for $0. A new key reads again.
Test values
A sk_test_ key answers these the same way every time, at $0 (every test value).
| Test value | Always returns | What it is for |
|---|---|---|
venue: | {"state": | Skips the approval page and returns a connected test Integration that reaches no real mailbox, so the calls after it run end to end. |
maxCost: | Refuses with max-cost | Any priced call with a maxCost of 0.0001 is refused before it spends: the price is above the cap. |
rate-limited.test | Refuses with rate-limited | Any call naming this hostname answers 429 with Retry-After, so your retry logic runs. |
sources-busy.test | Refuses with sources-busy | Any call naming this hostname answers 503 as if every route were busy, and nothing is spent. |
Used by
- Jobs: Measure · Run ads
- Integrations: The CRM you already use