Rough notes — this flow is in early development and the details below may
change.
Prerequisites
- Callback allowlist. Every
callback_urlyou use must be on Devin’s allowlist for your integration. This is configured by Cognition — send us the exact URLs ahead of time. A URL that is not on the list is rejected. - Outposts enabled. The customer’s account must have Outposts enabled.
- Admin authorization. Authorizing a connection requires a Devin admin with both enterprise-settings and service-user management rights. The partner never needs a Devin token — the admin authorizes it in their own browser session.
Flow overview
1. Generate a PKCE verifier and challenge
On your backend, per connection attempt:- Generate a high-entropy, random
code_verifier: 43–128 characters from the unreserved alphabet[A-Za-z0-9-._~](e.g.base64url(random 32 bytes)with padding stripped). - Derive the
code_challengeas the unpadded base64url of the SHA-256 of the verifier (PKCE “S256”):
code_verifier server-side (keyed to whatever state you use to correlate the eventual callback). Never send the verifier to the browser — only the challenge leaves your backend.
2. Redirect the admin to the connect page
Send the customer’s admin to Devin’s connect page with the challenge and your callback:
If the admin isn’t signed in, the connect page stashes these params and prompts them to sign in first, then resumes.
3. Admin confirms
The connect page shows a confirmation with an editable outpost name and platform (and youroutpost_image if provided). When the admin clicks Connect, Devin validates permissions, the callback allowlist, and that the outpost name is free, stores an encrypted, single-use code (10-minute TTL), and redirects back to your app with the one-time code.
No outpost or service user exists yet — they are created only when the code is redeemed (step 5). An unredeemed code simply expires.
4. Devin redirects the code to your callback
The browser is redirected to yourcallback_url with the code appended:
5. Exchange the code server-to-server
From your backend, look up thecode_verifier you stored in step 1 and redeem the code at the token endpoint. This is a form-encoded, OAuth-style token request:
6. Receive the credentials
On success Devin creates the outpost and a service user scoped to run the outpost worker, and returns:Cache-Control: no-store — do not cache them.
7. Run outpost workers
Storeaccess_token and api_base_url securely and use the token as a bearer credential to run outpost workers against the outpost.
Error handling
The token endpoint follows RFC 6749 §5.2. An unknown, expired, already-redeemed (replayed), or PKCE-mismatched code returns400:
invalid_grant as terminal: discard the stored code_verifier and restart the flow from step 1.
Security notes
- The token never touches the browser. Only the single-use code is relayed via redirect; the service-user token is returned solely from the server-to-server exchange.
- PKCE binds the code to you. The code is useless without the
code_verifierheld only on your backend, so intercepting the redirect (or the code) is not enough to redeem it. - Codes are single-use and short-lived. Redemption atomically consumes the code; it also expires after 10 minutes.
- Callback URLs are allowlisted. Devin only relays a code to a
callback_urlCognition has pre-approved for your integration. - Verify the code is for the requesting user. Confirm that the code returned to your callback belongs to the same user who originally requested the connection. This prevents an attacker from tricking a user into unsuspectingly binding Devin to a sandbox the attacker controls.
- Keep
outpost_namesensible. The admin may override it; the name you pass is only a suggestion.

