Table of Contents

OAuth clients

Set up OAuth 2.0 Client Credentials for machine-to-machine access to the Management API

Using this node, you can create new OAuth client credentials (Client ID and Client Secret) to authenticate machine-to-machine requests against the Management API. This follows the procedure outlined in the OAuth 2.0 Client Credentials grant (RFC 6749 §4.4).

This is not an interactive login flow for end-users — there is no browser redirect, no authorization code, and no user interaction. A client presents its credentials, receives a short-lived token, and uses that token to call the API.

To use this, you need administrator-level access to the DynamicWeb backend and access to the /admin/api management API endpoint.

Tip

When to use OAuth vs API keys

Both OAuth clients and API keys grant bearer-token access to the Management API. Choose based on how the consuming system works:

API keys OAuth clients
Auth model Static token bound to a user account Client Credentials flow — standard OAuth 2.0
Secret rotation Delete and recreate the key Delete and recreate the client
Identity Tied to the creating user's permissions Backed by a dedicated service account
Library support Custom header only Any OAuth 2.0 client library works
Best for Quick scripts, testing, simple automations Production integrations, CI/CD, the DynamicWeb CLI 2.0+

Typical OAuth client use cases:

  • Backend integrations — data sync, ERP/PIM pushes, or external systems that call the Management API on a schedule or in response to events
  • DynamicWeb CLI 2.0+ — authenticates against solutions using OAuth
  • CI/CD pipelines — deploy, build, or publish content as part of an automated workflow

Basic implementation flow

To implement OAuth authentication for the Management API follow these steps:

  1. Register an OAuth client
  2. Request a token
  3. Call the management API

Register an OAuth client

In the backend, go to Settings > System > Developer > OAuth and click Create new OAuth client.

Field Description
Name Display name for the client — visible in the client list
Description Optional free-text note (e.g. what system uses this client)
Allow backend login Must be enabled for the client to authenticate against the Management API. If the client's service account inherits this permission from a user group, the field is read-only.
Expiry date Optional. If set, the client's credentials stop working after this date. Leave blank for no expiry.

After saving, the system generates a Client ID and a Client Secret.

Warning

The Client Secret is displayed once. Copy it immediately and store it securely — it cannot be retrieved later. If you lose it, delete the client and create a new one.

Behind the scenes, DynamicWeb creates a dedicated service account user (oauth_{clientId}) that owns the client's permissions. This account is automatically deleted when you delete the OAuth client.

Request a token

POST the client credentials to the token endpoint. The endpoint accepts both JSON and form-encoded bodies.

JSON bodyPOST /Admin/OAuth/token

POST /Admin/OAuth/token HTTP/1.1
Host: yoursite.example.com
Content-Type: application/json

{
  "grant_type": "client_credentials",
  "client_id": "a1b2c3d4e5f6...",
  "client_secret": "secret..."
}

Form-encoded bodyPOST /Admin/OAuth/token/form

POST /Admin/OAuth/token/form HTTP/1.1
Host: yoursite.example.com
Content-Type: application/x-www-form-urlencoded

grant_type=client_credentials&client_id=a1b2c3d4e5f6...&client_secret=secret...

A successful response returns a JWT and its expiry timestamp:

{
  "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
  "expires": "2026-04-13T14:35:00Z"
}

Tokens expire after 5 minutes. There is no refresh token — request a new token when the current one expires.

Error responses:

Status Body Cause
400 {"error": "unsupported_grant_type"} grant_type is not client_credentials
400 {"error": "invalid_client"} client_id or client_secret missing
401 {"error": "invalid_client"} Credentials are wrong or the client has expired
403 {"error": "access_denied"} The client's service account does not have backend access

Call the Management API

Use the token as a bearer token in the Authorization header — the same way you would use an API key:

GET /dwapi/content/pages?WebsiteId=1 HTTP/1.1
Host: yoursite.example.com
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...

Examples

Here are two complete examples of how to to curl or HttpClient to request and use an OAuth token.

curl — full flow

# Request a token
TOKEN=$(curl -s -X POST https://yoursite.example.com/Admin/OAuth/token \
  -H "Content-Type: application/json" \
  -d '{
    "grant_type": "client_credentials",
    "client_id": "'"$CLIENT_ID"'",
    "client_secret": "'"$CLIENT_SECRET"'"
  }' | jq -r '.token')

# Use the token
curl -s https://yoursite.example.com/dwapi/content/pages?WebsiteId=1 \
  -H "Authorization: Bearer $TOKEN"

C# — HttpClient

using System.Net.Http.Json;
using System.Net.Http.Headers;

var http = new HttpClient { BaseAddress = new Uri("https://yoursite.example.com") };

// Request a token
var tokenResponse = await http.PostAsJsonAsync("/Admin/OAuth/token", new
{
    grant_type = "client_credentials",
    client_id = Environment.GetEnvironmentVariable("DW_CLIENT_ID"),
    client_secret = Environment.GetEnvironmentVariable("DW_CLIENT_SECRET")
});

var result = await tokenResponse.Content.ReadFromJsonAsync<TokenResult>();

// Use the token
http.DefaultRequestHeaders.Authorization =
    new AuthenticationHeaderValue("Bearer", result.Token);

var pages = await http.GetStringAsync("/dwapi/content/pages?WebsiteId=1");

record TokenResult(string Token, DateTime Expires);

Security considerations

Keep these practices in mind when working with OAuth clients:

  • Store secrets in environment variables or a secret manager — never commit them to source control
  • Rotate credentials by creating a new OAuth client and updating consumers before deleting the old one
  • Revoke access by deleting the OAuth client. Outstanding tokens remain valid until they expire (up to 5 minutes)
  • Use expiry dates on clients that are created for time-limited work, so credentials automatically stop working
To top