Request access OAuth client registration is handled by the OnePageCRM team β€” request access to get credentials. Learn more

OAuth

OAuth Quickstart

Get credentials, complete the authorization flow, and make your first authenticated API call.

Last updated Jul 14, 2026

This guide walks through the full Authorization Code + PKCE flow. By the end you will have a working client_id, an access token, and a live API call.

Prerequisites: Decide whether your app is a public or confidential client before you start. Have your redirect URI ready.


Step 1: Get client credentials

Request client credentials from the OnePageCRM team. You’ll need:

  • Your application name β€” users see it on the consent screen
  • Your redirect URI(s): the URL OnePageCRM will redirect users to after they approve your app β€” https, or http://localhost / http://127.0.0.1 for development
  • Client type: public (browser/mobile app) or confidential (server-side app)

Registration is handled manually and can take a few days β€” request it before you plan to build. You’ll receive your client_id (and client_secret for confidential clients).


Step 2: Generate PKCE values

Before redirecting the user, generate a code_verifier and code_challenge. These are single-use values that tie the token exchange to this specific login attempt.

const array = new Uint8Array(64)
crypto.getRandomValues(array)
const codeVerifier = btoa(String.fromCharCode(...array))
.replace(/\+/g, '-').replace(/\//g, '_').replace(/=/g, '')

const encoded = new TextEncoder().encode(codeVerifier)
const digest = await crypto.subtle.digest('SHA-256', encoded)
const codeChallenge = btoa(String.fromCharCode(...new Uint8Array(digest)))
.replace(/\+/g, '-').replace(/\//g, '_').replace(/=/g, '')

// Store for use in the callback
sessionStorage.setItem('code_verifier', codeVerifier)

Step 3: Redirect the user to OnePageCRM

Send the user to the authorization endpoint. On mobile, use the platform’s secure browser API, not a WebView.

const state = crypto.randomUUID()
sessionStorage.setItem('oauth_state', state)

const params = new URLSearchParams({
response_type: 'code',
client_id: 'YOUR_CLIENT_ID',
redirect_uri: 'https://myapp.example.com/callback',
scope: 'crm.readonly',
state,
code_challenge: codeChallenge,
code_challenge_method: 'S256',
})

window.location.href = `https://secure.onepagecrm.com/oauth/authorize?${params}`

Step 4: Exchange the code for tokens

After the user approves, OnePageCRM redirects back with ?code=...&state=.... Verify the state, then exchange the code immediately. It expires in 10 minutes and is single-use.

curl -X POST https://secure.onepagecrm.com/oauth/token \
-H "Content-Type: application/x-www-form-urlencoded" \
-d "grant_type=authorization_code" \
-d "code=AUTH_CODE" \
-d "redirect_uri=https://myapp.example.com/callback" \
-d "client_id=YOUR_CLIENT_ID" \
-d "code_verifier=YOUR_CODE_VERIFIER"

You receive:

{
  "access_token": "k2tV5VE1b3...",
  "token_type": "Bearer",
  "expires_in": 3600,
  "scope": "crm.readonly",
  "aud": "https://app.onepagecrm.com",
  "refresh_token": "dGhpcyBpcyBh..."
}

The aud field is the CRM API base URL for this user’s account β€” it may be a regional host rather than app.onepagecrm.com. Always build API URLs from aud instead of hard-coding a host. Store access_token in memory and refresh_token securely.


Step 5: Make an API request

# Base URL comes from the token response's aud field
curl https://app.onepagecrm.com/api/v3/contacts.json \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN"

Step 6: Renew the access token

Access tokens expire after 60 minutes. Use the refresh token to get a new one silently, with no user interaction required.

curl -X POST https://secure.onepagecrm.com/oauth/token \
-H "Content-Type: application/x-www-form-urlencoded" \
-d "grant_type=refresh_token" \
-d "refresh_token=YOUR_REFRESH_TOKEN" \
-d "client_id=YOUR_CLIENT_ID"

Public clients: Every refresh response includes a new refresh token. Always replace the old one. Reusing a rotated token revokes the entire session.


Next steps

  • Reference: every endpoint, parameter, error code, and security detail.