Develop
Authentication
API keys for server-to-server, OAuth for third-party apps, and signed webhooks for inbound events.
Bearer authentication
Every API request is authenticated with a bearer token in the Authorization header. Requests without a valid token return 401 Unauthorized.
curl https://api.nodedata.dev/v1/models/acme/grasp-policy-v2 \
-H "Authorization: Bearer $NODE_DATA_API_KEY"OAuth 2.0 for third-party apps
If you are building a tool that connects to other Node Data accounts (for example, a benchmarking dashboard), use OAuth 2.0 with PKCE. Register your app in Dashboard → OAuth apps.
# 1. Redirect the user to the authorize endpoint
https://nodedata.dev/oauth/authorize
?client_id=cli_01HZ...
&redirect_uri=https://your.app/callback
&scope=models:read+listings:read
&state=<csrf-token>
&response_type=code
# 2. Exchange the authorization code for tokens
curl -X POST https://api.nodedata.dev/oauth/token \
-d grant_type=authorization_code \
-d code=<code-from-callback> \
-d client_id=cli_01HZ... \
-d client_secret=$OAUTH_SECRET \
-d redirect_uri=https://your.app/callbackRequesting scopes
Ask for the narrowest set of scopes that lets your app function. Users see the scope list on the consent screen and apps that ask for more than they need are flagged in review.
Webhook signatures
Webhook bodies are signed with HMAC-SHA256 using the secret shown when you create the endpoint. The signature lives in the nd-signature header. Always verify the signature and the timestamp tolerance before trusting the payload.
import { verifyWebhook } from "@nodedata/sdk";
export async function POST(req: Request) {
const signature = req.headers.get("nd-signature")!;
const body = await req.text();
const event = verifyWebhook({
payload: body,
signature,
secret: process.env.NODE_DATA_WEBHOOK_SECRET!,
tolerance: 300, // seconds
});
switch (event.type) {
case "listing.purchased":
await grantAccess(event.data);
break;
case "payout.paid":
await reconcileLedger(event.data);
break;
}
return new Response("ok");
}Reject stale events
Browser sessions
Sessions on nodedata.dev use short-lived signed cookies with a refresh rotation. They are scoped to the browser and cannot be used from server code. For server code, always use an API key.
Authentication errors
| Status | Code | Meaning |
|---|---|---|
| 401 | missing_credentials | No bearer or session present |
| 401 | invalid_key | Key is malformed or revoked |
| 403 | scope_required | Key is valid but lacks the required scope |
| 403 | forbidden_resource | Key is valid but cannot access this resource |