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:

FieldRequiredDescription
App nameYesDisplayed to users when they authorize your app
App categoryYesCategory used for marketplace listing
Short descriptionYesOne-liner shown on the marketplace listing
App logoYes (for marketplace)Square image identifying your app
DescriptionNoFull description visible to Vibe users
How it worksNoExplanation of what your app does with Vibe data
App screenshotsNoImages 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.

FieldRequired for MarketplaceDescription
Company domainNoYour company's website
Support emailYesContact email shown to users after installation
Documentation URLNoLink to your integration docs
Support website URLNoLink 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_credentials to 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
ParameterRequiredDescription
client_idYesYour application's client ID
redirect_uriYesURL to redirect the user after authorization. Must match a registered redirect URI for your app.
response_typeYesMust be code
scopeYesSpace-separated list of scopes to request (e.g. campaigns:read)
stateYesAn 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

FieldTypeDescription
access_tokenstringJWT token to use in API requests. TTL 1 hour.
refresh_tokenstringToken used to obtain a new access token. Only present in the Authorization Code flow. TTL 90 days.
token_typestringAlways Bearer
expires_inintegerAccess 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

400 and 401 responses 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.

ErrorDescription
invalid_clientClient authentication failed. Check your client_id and client_secret.
invalid_grantThe authorization code is invalid, expired, or already used.
invalid_requestA required parameter is missing or malformed.
invalid_scopeOne or more of the requested scopes are invalid or not permitted for your client.
access_deniedThe user denied the authorization request.
unsupported_grant_typeThe requested grant type is not supported.

Error responses from the token endpoint are JSON:

{
  "error": "invalid_client",
  "error_description": "Client authentication failed."
}