Unlok API

OAuth2 & Developer Portal Documentation

View OpenAPI Specification

Overview

The Unlok API allows third-party vendors to build integrations that access user data with their explicit consent. We use OAuth 2.0 with PKCE (Proof Key for Code Exchange) to ensure secure authorization.

This guide walks you through the complete integration process:

  1. Submit your registration form to developers@unlok.com
  2. Receive your app credentials
  3. Implement the OAuth2 authorization flow
  4. Call APIs on behalf of users

1. Getting Started

To register with Unlok, please fill in the form below and send it to developers@unlok.com. Our team will review your submission and follow up with your credentials.

1

Company / Vendor Details

Provide the following information about your company:

{
  "companyName": "Acme Trading Corp",
  "companyWebsite": "https://acme-trading.com",
  "businessEmail": "dev@acme-trading.com",
  "country": "US",
  "phone": "+1-555-123-4567"
}
2

App Details

Provide the following information about the application you want to register:

{
  "appName": "Trading Bot Pro",
  "description": "Automated trading signals and portfolio management",
  "logoUrl": "https://acme-trading.com/logo.png",
  "homepageUrl": "https://acme-trading.com",
  "supportEmail": "support@acme-trading.com",
  "supportUrl": "https://acme-trading.com/support",
  "privacyPolicyUrl": "https://acme-trading.com/privacy",
  "termsOfServiceUrl": "https://acme-trading.com/terms",
  "redirectUris": ["https://acme-trading.com/callback"]
}
ℹ️ What happens next: Once we receive your form, our team will verify your details and provision your app credentials. You will receive a clientId and clientSecret at your businessEmail to get started.

2. Authorization Flow (OAuth2 + PKCE)

Unlok uses the Authorization Code flow with PKCE. This is the most secure OAuth2 flow for user authorization.

┌──────────────┐      ┌──────────────┐      ┌──────────────┐
│   End User   │      │   Your App   │      │    Unlok     │
└──────┬───────┘      └──────┬───────┘      └──────┬───────┘
       │                     │                     │
       │  1. Click "Login    │                     │
       │     with Unlok"     │                     │
       │────────────────────▶│                     │
       │                     │                     │
       │                     │  2. Generate PKCE   │
       │                     │     code_verifier   │
       │                     │     code_challenge  │
       │                     │                     │
       │  3. Redirect to /oauth/authorize          │
       │◀────────────────────┼────────────────────▶│
       │                     │                     │
       │                     │     4. Show login   │
       │                     │        + consent    │
       │◀──────────────────────────────────────────│
       │                     │                     │
       │  5. User approves   │                     │
       │─────────────────────────────────────────▶ │
       │                     │                     │
       │  6. Redirect with ?code=xxx               │
       │◀──────────────────────────────────────────│
       │                     │                     │
       │                     │  7. POST /oauth/token
       │                     │     code + verifier │
       │                     │────────────────────▶│
       │                     │                     │
       │                     │  8. access_token    │
       │                     │     refresh_token   │
       │                     │◀────────────────────│
       │                     │                     │
       │  9. Access granted  │                     │
       │◀────────────────────│                     │
       │                     │                     │
        

Step-by-Step Implementation

1

Generate PKCE Challenge

Before redirecting the user, generate a PKCE code verifier and challenge:

// Generate random code_verifier (43-128 characters)
const codeVerifier = generateRandomString(64);

// Create code_challenge (SHA-256 hash, base64url encoded)
const codeChallenge = base64url(sha256(codeVerifier));

// Store codeVerifier securely (session/cookie) — you'll need it later
2

Redirect to Authorization

Build the authorization URL and redirect the user:

const authUrl = new URL('https://api.unlok.com/oauth/authorize');
authUrl.searchParams.set('response_type', 'code');
authUrl.searchParams.set('client_id', 'ulk_cid_abc123');
authUrl.searchParams.set('redirect_uri', 'https://yourapp.com/callback');
authUrl.searchParams.set('scopes', 'orders:read,account:read');
authUrl.searchParams.set('state', generateRandomState());  // CSRF protection
authUrl.searchParams.set('code_challenge', codeChallenge);
authUrl.searchParams.set('code_challenge_method', 'S256');

// Redirect user to Unlok
window.location.href = authUrl.toString();
3

Handle the Callback

After the user approves, Unlok redirects back to your redirect_uri with a code:

// Your callback URL receives:
// https://yourapp.com/callback?code=ulk_ac_xyz789&state=xyzABC123

// 1. Verify the state matches what you stored (CSRF protection)
// 2. Extract the code parameter
4

Exchange Code for Tokens

Call POST /oauth/token from your backend to exchange the code:

const response = await fetch('https://api.unlok.com/oauth/token', {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({
    grant_type: 'AUTH_CODE',
    code: 'ulk_ac_xyz789',
    redirect_uri: 'https://yourapp.com/callback',
    client_id: 'ulk_cid_abc123',
    client_secret: process.env.CLIENT_SECRET,
    code_verifier: storedCodeVerifier  // From step 1
  })
});

const { access_token, refresh_token, expires_in } = await response.json();

See the full API reference.

5

Make API Calls

Use the access token in the Authorization header:

const response = await fetch('https://api.unlok.com/api/orders', {
  headers: {
    'Authorization': `Bearer ${access_token}`
  }
});
6

Refresh Tokens

When the access token expires, use the refresh token to get a new one:

const response = await fetch('https://api.unlok.com/oauth/token', {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({
    grant_type: 'REFRESH_TOKEN',
    refresh_token: storedRefreshToken,
    client_id: 'ulk_cid_abc123',
    client_secret: process.env.CLIENT_SECRET
  })
});

const { access_token, refresh_token } = await response.json();
// Store the new refresh_token — it replaces the old one
ℹ️ Token Lifetime:
  • Access tokens expire after 1 hour (3600 seconds)
  • Refresh tokens expire after 30 days
  • Refresh tokens are single-use — each refresh returns a new one

3. API Reference

For complete API documentation with request/response schemas, see the OpenAPI specification.

OAuth2 Endpoints

POST /oauth/token
POST /oauth/revoke
GET /oauth/authorize
GET /oauth/userinfo

Accounts Endpoints

GET /accounts
GET /accounts/{accountId}/positions
GET /accounts/{accountId}/position
GET /accounts/{accountId}/margin
GET /accounts/{accountId}/portfolios

Banking Endpoints

GET /banking/{accountId}/balance
GET /banking/{accountId}/balance/{ccy}
GET /banking/{accountId}/activity
GET /banking/{accountId}/txn-activity
POST /banking/deposit
POST /banking/withdraw
POST /banking/cancel-txn

Orders Endpoints

GET /oms/{accountId}/order/rules
GET /oms/{accountId}/orders
GET /oms/{accountId}/order/{orderId}
GET /oms/{accountId}/trades
POST /oms/what-if
POST /oms/order
DELETE /oms/order