---
title: "Connect accounts via the API"
description: "Run the full BYOK OAuth flow from your own backend with an API key, and send your users back to your app with return_url."
section: "Guides"
url: https://dravo.dev/docs/guides/connect-accounts
---
# Connect accounts via the API

You can connect a social account end to end from your own backend using just an
API key (no dashboard required). This is the "Connect" pattern: you start the
OAuth flow for **your** user and bring them back to **your** app afterwards.
Background: [BYOK](/docs/concepts/byok) and the [OAuth API](/docs/api/oauth).

## The Connect flow

1. Create a BYOK [OAuth app](/docs/api/oauth) for the provider, with the URLs
   your users may return to (`allowed_return_urls`).
2. Call `start` with a `return_url` to get the provider's authorize URL.
3. Redirect your user there. After consent, Dravo connects the account and
   redirects the user to your `return_url`.

The OAuth app belongs to you, so platform App Review is yours (see
[BYOK](/docs/concepts/byok)).

## 1. Create an OAuth app

Store your provider `client_id`/`client_secret` and the return URLs allowlist.
The secret is encrypted at rest and never returned.

```bash
curl -X POST https://api.dravo.dev/v1/oauth-apps \
  -H "Authorization: Bearer $DRAVO_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "provider": "x",
    "name": "My X App",
    "client_id": "...",
    "client_secret": "...",
    "allowed_return_urls": ["https://app.acme.com/connect"]
  }'
```

The response includes the `redirect_uri` you must register on your provider app.

## 2. Start the flow

Ask for the authorize URL and pass where the user should land afterwards. The
`return_url` must match an `allowed_return_urls` entry by origin and path prefix
(so `https://app.acme.com/connect` also covers
`https://app.acme.com/connect/done`).

```bash
curl "https://api.dravo.dev/v1/oauth/x/start?return_url=https://app.acme.com/connect" \
  -H "Authorization: Bearer $DRAVO_API_KEY"
```

```json
{
  "authorize_url": "https://twitter.com/i/oauth2/authorize?client_id=…&state=…"
}
```

Redirect your user to `authorize_url`. If the `return_url` is not in the
allowlist, the request fails with `400`.

## 3. Handle the return

After consent, the provider calls Dravo's callback (signed `state`, no auth),
the account is connected, and the user is redirected to your `return_url` with a
query string:

- Success: `https://app.acme.com/connect?connected=x`
- Failure: `https://app.acme.com/connect?oauth_error=<reason>`

List the connected accounts any time with
[`GET /v1/accounts`](/docs/api/accounts) and start
[publishing](/docs/api/publish).

## Manual alternative

If you already hold a provider access token (advanced BYOK), skip OAuth and
register the account directly with
[`POST /v1/accounts`](/docs/api/accounts). The interactive flow above is simpler
and safer for most setups.
