Skip to content
  • There are no suggestions because the search field is empty.

How to Authenticate with the Convert API Using OAuth

Authenticating with the Convert API using OAuth allows third-party services to securely access user accounts and projects. 

Author: George F. Crewe

THIS ARTICLE WILL HELP YOU:

Overview

Authenticating with the Convert API using OAuth allows third-party services to securely access user accounts and projects. Convert utilizes the Proof Key for Code Exchange (PKCE) flow to ensure a highly secure authentication process. Follow the steps below to set up your OAuth client and obtain your access token.

Step 1: Create an OAuth Client

First, you need to register your third-party application within your Convert account.

  • Log in to your Convert account.
  • Navigate to Profile Settings > OAuth Clients.
  • Click Create new client.
  • Fill in the required details.

Important: Pay close attention to the Callback URL. This must be the exact URL of the third-party service where the user will be redirected after granting access.

Once created, you will receive a client_id, which you will use in the following steps.

Step 2: Construct the Authorization URL

To initiate the authentication process, your application must direct the user to Convert's authorization page. Because Convert uses the PKCE flow, you first need to generate two cryptographic strings:

  • code_verifier: A highly secure, random string (store this securely, as you will need it in Step 4).
  • code_challenge: The Base64URL-encoded SHA-256 hash of your code_verifier. (See the Developer Appendix at the bottom of this article for code examples on how to generate these).

Next, construct the authorization link using the following format:

https://app.convert.com/auth/oauth/authorize?client_id=CLIENT_ID&state=RANDOM_STRING&scope=selected_accounts_projects&response_type=code&code_challenge=generatedCodeChallenge

URL Parameters:

  • client_id: The Client ID generated in Step 1.
  • state: A random 10-20 character string used for CSRF (Cross-Site Request Forgery) protection.
  • scope: The level of access being requested (e.g., selected_accounts_projects).
  • response_type: Must be set exactly to code.
  • code_challenge: The hashed string you generated using your code_verifier.

Step 3: User Authorization and Callback

When the user opens the authorization URL in their browser:

  1. They will be prompted by Convert to select the specific scopes (accounts or projects) they wish to grant access to.
  2. After approving the scopes, Convert will automatically redirect the user back to the Callback URL you specified in Step 1.
  3. The callback URL will include an authorization code appended as a query parameter.

Step 4: Obtain the Access Token

You must now exchange the authorization code for an access_token. Make a POST request to the Convert API token endpoint:

Endpoint:

POST https://api.convert.com/api/v2/auth/oauth/token

Request Body (JSON):

{
  "grant_type": "authorization_code",
  "code": "YOUR_RECEIVED_CODE",
  "client_id": "YOUR_CLIENT_ID",
  "code_verifier": "YOUR_STORED_CODE_VERIFIER"
}

Body Parameters:

  • grant_type: Keep this as exactly "authorization_code".
  • code: The authorization code you received from the callback URL in Step 3.
  • client_id: Your OAuth Client ID.
  • code_verifier: The original, unhashed secret string you generated at the beginning of Step 2.

Step 5: Make API Requests

If your POST request is successful, the response will contain your access_token. You can now use this token to authenticate your requests to the Convert API. Include the token in the headers of your API requests like so:

Authorization: Bearer

Client-Side JavaScript

Developer Appendix: Generating PKCE Strings

To successfully execute Step 2, you must generate a compliant PKCE pair. The code_verifier must be a cryptographically random string between 43 and 128 characters long. The code_challenge must be a Base64-URL-encoded SHA-256 hash of that verifier.

Here are implementation examples in standard languages:

JavaScript (Browser API):

// 1. Generate a secure code_verifier
function generateRandomString(length) {
    const possible = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-._~';
    const values = crypto.getRandomValues(new Uint8Array(length));
    return values.reduce((acc, x) => acc + possible[x % possible.length], "");
}
const codeVerifier = generateRandomString(64);
// 2. Generate the code_challenge
async function generateCodeChallenge(verifier) {
    const encoder = new TextEncoder();
    const data = encoder.encode(verifier);
    const digest = await window.crypto.subtle.digest('SHA-256', data);
    // Base64URL encode the hash
    return btoa(String.fromCharCode.apply(null, [...new Uint8Array(digest)]))
        .replace(/\+/g, '-')
        .replace(/\//g, '_')
        .replace(/=+$/, '');
}
// Example usage:
// const codeChallenge = await generateCodeChallenge(codeVerifier);

Node.js (Backend JavaScript):

const crypto = require('crypto');
// 1. Generate a secure code_verifier
function generateRandomString(length) {
    return crypto.randomBytes(length)
        .toString('base64url')
        .replace(/[^a-zA-Z0-9\-._~]/g, '')
        .substring(0, length);
}
const codeVerifier = generateRandomString(64);
// 2. Generate the code_challenge
function generateCodeChallenge(verifier) {
    return crypto.createHash('sha256')
        .update(verifier)
        .digest('base64url');
}
// Example usage:
// const codeChallenge = generateCodeChallenge(codeVerifier);

Python:

import base64
import hashlib
import os
import re
# 1. Generate a secure code_verifier
# Generate 40 random bytes, base64url encode them, and strip invalid characters
raw_verifier = base64.urlsafe_b64encode(os.urandom(40)).decode('utf-8')
code_verifier = re.sub(r'[^a-zA-Z0-9\-._~]', '', raw_verifier)
# 2. Generate the code_challenge
# Hash the verifier using SHA-256
sha256_hash = hashlib.sha256(code_verifier.encode('utf-8')).digest()
# Base64URL encode the hash and strip padding '='
code_challenge = base64.urlsafe_b64encode(sha256_hash).decode('utf-8').rstrip('=')
# You can now use code_verifier and code_challenge in your OAuth flow