OAuth in 5 minutes
Connect a third-party app to a Pact workspace with the Authorization Code + PKCE flow.
If you are building an app that other people connect to their Pact workspace, use OAuth — not a shared API key. OAuth lets a workspace admin grant your app a scoped, revocable token without ever handing over a long-lived secret.
Use a static API key only for your own back-office scripts.
Step 1 — Register your app
A workspace admin registers OAuth apps under Admin → API & developers (/admin/api-developers). You receive a client_id and, for confidential clients, a client_secret. You also set:
- Redirect URIs — exact URLs Pact may send the user back to.
- Scopes — the permissions your app may request. See the scope reference.
Public clients (single-page apps, mobile, CLIs) must use PKCE and do not get a client secret.
Step 2 — Send the user to authorize
Redirect the workspace user to /oauth/authorize with a PKCE challenge:
https://app.pact.place/oauth/authorize
?response_type=code
&client_id=YOUR_CLIENT_ID
&redirect_uri=https://yourapp.com/callback
&scope=read:contacts%20write:contacts
&state=RANDOM_STATE
&code_challenge=BASE64URL_SHA256_OF_VERIFIER
&code_challenge_method=S256
The user reviews the requested scopes and approves. Pact redirects to your redirect_uri with ?code=…&state=…. Verify state matches what you sent.
import crypto from "node:crypto";
const verifier = crypto.randomBytes(32).toString("base64url");
const challenge = crypto.createHash("sha256").update(verifier).digest("base64url");
// store `verifier` in the session; send `challenge` in the authorize URL
Step 3 — Exchange the code for tokens
curl -X POST https://app.pact.place/oauth/token \
-H "Content-Type: application/x-www-form-urlencoded" \
-d grant_type=authorization_code \
-d code=THE_CODE \
-d redirect_uri=https://yourapp.com/callback \
-d client_id=YOUR_CLIENT_ID \
-d code_verifier=THE_VERIFIER
You get an access token (valid 1 hour), a refresh token (valid 30 days), and the granted scope:
{
"access_token": "…",
"token_type": "Bearer",
"expires_in": 3600,
"refresh_token": "…",
"scope": "read:contacts write:contacts"
}
Step 4 — Call the API
Use the access token exactly like an API key:
curl https://app.pact.place/v1/contacts?limit=10 \
-H "Authorization: Bearer ACCESS_TOKEN"
When it expires, refresh it:
curl -X POST https://app.pact.place/oauth/token \
-H "Content-Type: application/x-www-form-urlencoded" \
-d grant_type=refresh_token \
-d refresh_token=THE_REFRESH_TOKEN \
-d client_id=YOUR_CLIENT_ID
Server-to-server (no user)
For backend integrations with no human in the loop, use the client credentials grant with a confidential client:
curl -X POST https://app.pact.place/oauth/token \
-H "Content-Type: application/x-www-form-urlencoded" \
-d grant_type=client_credentials \
-d client_id=YOUR_CLIENT_ID \
-d client_secret=YOUR_CLIENT_SECRET \
-d scope=read:deals
Revocation
Workspace admins can revoke your app at any time from the Installed tab of Admin → API &
developers, and you can revoke a token yourself with POST /oauth/revoke. Always request the
minimum scopes — admins approve faster and trust least-privilege apps.