@ucap/sdk

Hand-written, zero-dependency TypeScript client for the UCAPTM public API. Works in browsers, Node ≥ 18, Deno, Bun, and Cloudflare Workers.

Install

During the developer preview the SDK ships as a workspace package. Drop the packages/sdk folder into your monorepo, or grab the tarball from your client contact.

# inside your monorepo
bun add @ucap/sdk@workspace:*

# or from a tarball
bun add ./ucap-sdk-0.1.0.tgz

Quickstart — user OAuth

import { UcapClient, generateCodeVerifier, deriveCodeChallenge } from "@ucap/sdk";

const ucap = new UcapClient({
  baseUrl: "https://ucap.africa",
  clientId: process.env.UCAP_CLIENT_ID!,
});

// 1. Build the authorize URL
const verifier = generateCodeVerifier();
const challenge = await deriveCodeChallenge(verifier);
const state = crypto.randomUUID();

const url = ucap.oauth.buildAuthorizeUrl({
  redirectUri: "https://yourapp.com/callback",
  scope: ["consumer.profile.read"],
  state,
  challenge,
});
// → redirect the user to `url`

// 2. After the redirect back, exchange the code
const tokens = await ucap.oauth.exchangeCode({
  code,                       // from req.query.code
  redirectUri: "https://yourapp.com/callback",
  verifier,                   // pulled from session
});

// 3. Call the API
const profile = await ucap.me.getProfile(tokens.access_token);

Server-to-server

const ucap = new UcapClient({
  baseUrl: "https://ucap.africa",
  clientId: process.env.UCAP_CLIENT_ID!,
  clientSecret: process.env.UCAP_CLIENT_SECRET!,
});

const tokens = await ucap.oauth.clientCredentials([
  "sessions.create", "sessions.read",
]);

Error handling

Every non-2xx response throws UcapApiError with the server's code and message intact, plus the HTTP status.

import { UcapApiError } from "@ucap/sdk";

try {
  await ucap.me.getProfile(token);
} catch (err) {
  if (err instanceof UcapApiError && err.code === "insufficient_scope") {
    // re-prompt the user with the right scopes
  }
  throw err;
}

Surface

  • generateCodeVerifier() / deriveCodeChallenge(v)
  • UcapClient#startAuthorization(opts) → authorize URL
  • UcapClient#exchangeCode(opts) → tokens
  • UcapClient#refresh(refreshToken) → tokens
  • UcapClient#clientCredentials(opts) → tokens
  • UcapClient#revoke(token)
  • UcapClient#me.getProfile(token)
  • UcapClient#me.listDocuments(token)
  • UcapClient#me.listGrants(token)