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:
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 body — POST /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 body — POST /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