User API Tokens
Manage your personal API tokens. User tokens are owned by you and can access resources across all your account memberships.
Overview
Access user token management through cf.ApiTokens:
public class UserTokenService(ICloudflareApiClient cf)
{
public async Task<CreateApiTokenResult> CreatePersonalTokenAsync(string name)
{
return await cf.ApiTokens.CreateUserTokenAsync(
new CreateApiTokenRequest(
Name: name,
Policies: new[]
{
new CreateTokenPolicyRequest(
Effect: "allow",
PermissionGroups: new[] { new TokenPermissionGroupReference(groupId) },
Resources: new Dictionary<string, string>
{
["com.cloudflare.api.user"] = "*"
}
)
}
));
}
}
Warning
The token secret is only returned when created. Store it securely - it cannot be retrieved again.
Listing Tokens
With Pagination
var result = await cf.ApiTokens.ListUserTokensAsync(
new ListApiTokensFilters(Page: 1, PerPage: 50));
foreach (var token in result.Items)
{
Console.WriteLine($"{token.Name}: {token.Status}");
Console.WriteLine($" Last used: {token.LastUsedOn}");
Console.WriteLine($" Expires: {token.ExpiresOn}");
}
List All Tokens
await foreach (var token in cf.ApiTokens.ListAllUserTokensAsync())
{
Console.WriteLine($"{token.Name} [{token.Status}]");
}
Getting Token Details
var token = await cf.ApiTokens.GetUserTokenAsync(tokenId);
Console.WriteLine($"Name: {token.Name}");
Console.WriteLine($"Status: {token.Status}");
Console.WriteLine($"Created: {token.IssuedOn}");
Console.WriteLine($"Expires: {token.ExpiresOn}");
Console.WriteLine($"Last Used: {token.LastUsedOn}");
Creating Tokens
Basic Token
var result = await cf.ApiTokens.CreateUserTokenAsync(
new CreateApiTokenRequest(
Name: "My Personal Token",
Policies: new[]
{
new CreateTokenPolicyRequest(
Effect: "allow",
PermissionGroups: new[]
{
new TokenPermissionGroupReference(permissionGroupId)
},
Resources: new Dictionary<string, string>
{
["com.cloudflare.api.user"] = "*"
}
)
}
));
// IMPORTANT: Store this securely!
Console.WriteLine($"Token: {result.Value}");
Token with Expiration
var result = await cf.ApiTokens.CreateUserTokenAsync(
new CreateApiTokenRequest(
Name: "Temporary Token",
Policies: new[]
{
new CreateTokenPolicyRequest(
Effect: "allow",
PermissionGroups: new[] { new TokenPermissionGroupReference(groupId) },
Resources: new Dictionary<string, string>
{
["com.cloudflare.api.user"] = "*"
}
)
},
ExpiresOn: DateTime.UtcNow.AddYears(1)
));
Updating Tokens
// Disable a token
var updated = await cf.ApiTokens.UpdateUserTokenAsync(tokenId,
new UpdateApiTokenRequest(
Name: "Disabled Token",
Policies: existingPolicies,
Status: TokenStatus.Disabled
));
Deleting Tokens
await cf.ApiTokens.DeleteUserTokenAsync(tokenId);
Verifying Tokens
Check if the current token is valid:
var result = await cf.ApiTokens.VerifyUserTokenAsync();
Console.WriteLine($"Token ID: {result.Id}");
Console.WriteLine($"Status: {result.Status}");
if (result.ExpiresOn.HasValue)
{
var remaining = result.ExpiresOn.Value - DateTime.UtcNow;
Console.WriteLine($"Expires in: {remaining.Days} days");
}
Rolling (Rotating) Tokens
Generate a new secret for an existing token:
var newValue = await cf.ApiTokens.RollUserTokenAsync(tokenId);
// Store the new value securely
Console.WriteLine($"New token value: {newValue}");
Warning
Rolling a token immediately invalidates the old value.
Permission Groups
List Available Permission Groups
var result = await cf.ApiTokens.GetUserPermissionGroupsAsync();
foreach (var group in result.Items)
{
Console.WriteLine($"{group.Name} ({group.Id})");
}
List All Permission Groups
await foreach (var group in cf.ApiTokens.GetAllUserPermissionGroupsAsync())
{
Console.WriteLine($"{group.Name}: {group.Id}");
foreach (var scope in group.Scopes)
{
Console.WriteLine($" - {scope}");
}
}
User vs Account Tokens
| Feature | User Tokens | Account Tokens |
|---|---|---|
| Ownership | Personal | Account |
| Scope | All your memberships | Single account |
| Management | cf.ApiTokens.ListUserTokensAsync |
cf.ApiTokens.ListAccountTokensAsync |
| Best for | Personal automation | Shared team access |
Models Reference
ApiToken
| Property | Type | Description |
|---|---|---|
Id |
string |
Token identifier |
Name |
string |
Token name |
Status |
TokenStatus |
Token status |
Policies |
IReadOnlyList<TokenPolicy> |
Access policies |
IssuedOn |
DateTime? |
Creation timestamp |
ExpiresOn |
DateTime? |
Expiration timestamp |
NotBefore |
DateTime? |
Validity start |
LastUsedOn |
DateTime? |
Last usage |
TokenStatus (Extensible Enum)
TokenStatus represents the current state of an API token:
| Known Value | API Value | Description |
|---|---|---|
Active |
active |
Token is active and can be used for API requests |
Disabled |
disabled |
Token has been manually disabled |
Expired |
expired |
Token has passed its expiration date |
using Cloudflare.NET.ApiTokens.Models;
// Check token status
if (token.Status == TokenStatus.Active)
{
Console.WriteLine("Token is ready to use");
}
// Extensible for future status values
TokenStatus customStatus = "pending";
Common Patterns
Find Expiring Tokens
public async Task AlertExpiringTokensAsync(int daysWarning = 30)
{
var threshold = DateTime.UtcNow.AddDays(daysWarning);
await foreach (var token in cf.ApiTokens.ListAllUserTokensAsync())
{
if (token.ExpiresOn.HasValue && token.ExpiresOn.Value < threshold)
{
var remaining = token.ExpiresOn.Value - DateTime.UtcNow;
Console.WriteLine($"[WARNING] {token.Name} expires in {remaining.Days} days");
}
}
}
Rotate All Active Tokens
public async Task<Dictionary<string, string>> RotateAllTokensAsync()
{
var newTokens = new Dictionary<string, string>();
await foreach (var token in cf.ApiTokens.ListAllUserTokensAsync())
{
if (token.Status == TokenStatus.Active)
{
var newValue = await cf.ApiTokens.RollUserTokenAsync(token.Id);
newTokens[token.Name] = newValue;
Console.WriteLine($"Rotated: {token.Name}");
}
}
return newTokens;
}
Required Permissions
| Permission | Scope | Level |
|---|---|---|
| API Tokens | User | Read (for listing/get/verify) |
| API Tokens | User | Write (for create/update/delete/roll) |
Related
- Account API Tokens - Account-scoped tokens
- User Profile - Your profile settings