Start your OAuth flow
Creating an App
Before you can authenticate API requests, you need to register an application in the Vibe Developer Portal. This gives you a client_id and client_secret to use in the OAuth flows below.
App information
Fill in the App information tab:
| Field | Required | Description |
|---|---|---|
| App name | Yes | Displayed to users when they authorize your app |
| App category | Yes | Category used for marketplace listing |
| Short description | Yes | One-liner shown on the marketplace listing |
| App logo | Yes (for marketplace) | Square image identifying your app |
| Description | No | Full description visible to Vibe users |
| How it works | No | Explanation of what your app does with Vibe data |
| App screenshots | No | Images shown on the marketplace listing |
Authentication
On the Authentication tab, select OAuth as the authentication method, then configure:
Redirect URLs
Add every URL your app may redirect to after a user authorizes access. These must exactly match the redirect_uri values you send in your authorization requests. You can add multiple URLs (e.g. one for development, one for production).
Scopes
Select only the permissions your integration needs.
Support
Fill in the Support tab. At least one support contact method is required to publish your app to the Marketplace.
| Field | Required for Marketplace | Description |
|---|---|---|
| Company domain | No | Your company's website |
| Support email | Yes | Contact email shown to users after installation |
| Documentation URL | No | Link to your integration docs |
| Support website URL | No | Link to your support portal |
Publishing
Your app starts in Draft status. Once all required fields are filled in, click Publish to submit it for review and make it available in the Marketplace.
Your client_id and client_secret are available from your app's settings page after creation. Keep the client_secret secret — never expose it in client-side code or version control.
Base URL
All OAuth endpoints are available at:
https://api.vibe.co
Developer note — Pick the right grant
For server-to-server integrations with no end user, such as cron jobs, exports, and backends, use
client_credentials.When a Vibe user is signing into your app and granting your app access to their accounts, use
authorization_code.Don't use
client_credentialsto act on a user's account.
Authorization Code Flow
Use this flow when your application needs access to resources owned by a specific Vibe user. The user is redirected to Vibe to authenticate and approve access, then returned to your app with an authorization code you exchange for a token.
Step 1 — Redirect the user to Vibe
Send the user to the Vibe authorization endpoint with the following query parameters:
GET https://api.vibe.co/oauth2/auth
| Parameter | Required | Description |
|---|---|---|
client_id | Yes | Your application's client ID |
redirect_uri | Yes | URL to redirect the user after authorization. Must match a registered redirect URI for your app. |
response_type | Yes | Must be code |
scope | Yes | Space-separated list of scopes to request (e.g. campaigns:read) |
state | Yes | An opaque value you generate to prevent CSRF. You must verify this on the callback. |
Example redirect URL:
https://api.vibe.co/oauth2/auth?client_id=<YOUR_CLIENT_ID>&redirect_uri=https%3A%2F%2Fyourapp.com%2Fcallback&response_type=code&scope=campaigns%3Aread&state=abc123xyz
Step 2 — Handle the callback
After the user authorizes your app, Vibe redirects them to your redirect_uri with two query parameters:
GET https://yourapp.com/callback?code=<AUTHORIZATION_CODE>&state=<YOUR_STATE>
Before proceeding, verify that state matches the value you sent in Step 1. If it does not match, reject the request.
If the user denies access or an error occurs, the redirect will include error and error_description parameters instead:
GET https://yourapp.com/callback?error=access_denied&error_description=The+user+denied+access
Step 3 — Exchange the code for a token
Make a server-side POST request to exchange the authorization code for an access token. Never make this request from client-side code, as it requires your client secret.
POST https://api.vibe.co/oauth2/token
Content-Type: application/x-www-form-urlencoded
Authorization: Basic <BASE64(YOUR_CLIENT_ID:YOUR_CLIENT_SECRET)>
grant_type=authorization_code
&code=<AUTHORIZATION_CODE>
&redirect_uri=https://yourapp.com/callback
The Authorization header value is Basic followed by the Base64 encoding of <client_id>:<client_secret>.
Example response:
{
"access_token": "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9...",
"refresh_token": "ory_rt_...",
"token_type": "Bearer",
"expires_in": 3600
}Store the refresh_token securely. You will use it to obtain new access tokens without requiring the user to re-authorize. The access token expires after 1 hour.
Step 4 — Call the API
Include the access token as a Bearer token in the Authorization header of every API request:
GET https://api.vibe.co/*
Authorization: Bearer <ACCESS_TOKEN>
Token Response Reference
| Field | Type | Description |
|---|---|---|
access_token | string | JWT token to use in API requests. TTL 1 hour. |
refresh_token | string | Token used to obtain a new access token. Only present in the Authorization Code flow. TTL 90 days. |
token_type | string | Always Bearer |
expires_in | integer | Access token lifetime in seconds |
Access tokens are JWTs. You can inspect the payload by Base64-decoding the middle segment (between the two . characters). The payload contains standard claims such as sub, scope, iat, and exp. Do not rely on the token payload structure in your integration logic — use the API responses instead.
Tokens expire after the duration indicated by expires_in. Use the refresh_token from the Authorization Code flow to obtain a new access token without user interaction. The Client Credentials flow does not issue refresh tokens.
Refreshing Access Tokens
When an access token expires, use the refresh token to obtain a new one without requiring the user to re-authorize. This only applies to the Authorization Code flow — Client Credentials tokens cannot be refreshed.
POST https://api.vibe.co/oauth2/token
Content-Type: application/x-www-form-urlencoded
Authorization: Basic <BASE64(YOUR_CLIENT_ID:YOUR_CLIENT_SECRET)>
grant_type=refresh_token
&refresh_token=<YOUR_REFRESH_TOKEN>
Example response:
{
"access_token": "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9...",
"refresh_token": "ory_rt_...",
"token_type": "Bearer",
"expires_in": 3600
}Each refresh issues a new refresh token. Replace the stored refresh token with the one returned in the response — the previous token is invalidated.
Error Reference
Errors from the authorization endpoint and token endpoint follow OAuth 2.0 standard error codes.
Gotcha — OAuth error envelope
400and401responses from OAuth endpoints follow RFC 6749 §5.2:{'{'} "error": "invalid_grant", "error_description": "..." {'}'}.They do not use the Vibe error envelope. Parse both shapes in code that handles OAuth and the rest of the Vibe API.
| Error | Description |
|---|---|
invalid_client | Client authentication failed. Check your client_id and client_secret. |
invalid_grant | The authorization code is invalid, expired, or already used. |
invalid_request | A required parameter is missing or malformed. |
invalid_scope | One or more of the requested scopes are invalid or not permitted for your client. |
access_denied | The user denied the authorization request. |
unsupported_grant_type | The requested grant type is not supported. |
Error responses from the token endpoint are JSON:
{
"error": "invalid_client",
"error_description": "Client authentication failed."
}Updated 20 days ago