Create and authenticate a service user

Create a service user to set up integrations.

Service users are designed for automation. They persist regardless of employee turnover and enable granular permission control for API integrations.

In this tutorial, you will:

  • Get the account ID to assign the service user.
  • Identify available roles and permissions for the service user.
  • Create the service user.
  • Use the returned API token to authenticate your first API call as that service user.

Before you begin

Completed (or understand) How to make your first API call.
API token with the Account Administrator role and the ability to create service users.
Basic familiarity with REST APIs, JSON, and preferred coding language.
If using curl, jq installed. Use jq --version to verify.

Endpoint overview

PathMethodDescription
/account/api/v1/accountGETRetrieve a list of accounts you have access to
/account/api/v1/roleGETRetrieve a list of roles and associated permissions available to assign
/account/api/v1/userPOSTCreate a new service user with specified roles and permissions
/account/api/v1/user/meGETGet details about the currently authenticated user

Step 1: Get your account ID

Service users must be assigned to at least one account. You can find the account ID to assign using the /account/api/v1/account endpoint.

Request:

curl -X GET https://demo.one.digicert.com/account/api/v1/account \
  -H "x-api-key: ADMIN_API_KEY" \
  -H "Content-Type: application/json" | jq '.'
import requests

# Configuration
BASE_URL = "https://demo.one.digicert.com"
API_KEY = "ADMIN_API_KEY"

# Get accounts
response = requests.get(
    f"{BASE_URL}/account/api/v1/account",
    headers={
        "x-api-key": API_KEY,
        "Content-Type": "application/json"
    }
)

# Check response
if response.status_code == 200:
    accounts = response.json()
    print("Accounts retrieved successfully:")
    for account in accounts:
        print(f"  - {account['name']} (ID: {account['id']})")
else:
    print(f"Error {response.status_code}: {response.text}")
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import org.json.JSONArray;
import org.json.JSONObject;

public class AccountExample {
    
    private static final String BASE_URL = "https://demo.one.digicert.com";
    private static final String API_KEY = "YOUR_API_KEY";
    
    public static void main(String[] args) {
        try {
            HttpClient client = HttpClient.newHttpClient();
            
            HttpRequest request = HttpRequest.newBuilder()
                .uri(URI.create(BASE_URL + "/account/api/v1/account"))
                .header("x-api-key", API_KEY)
                .header("Content-Type", "application/json")
                .GET()
                .build();
            
            HttpResponse<String> response = client.send(
                request,
                HttpResponse.BodyHandlers.ofString()
            );
            
            if (response.statusCode() == 200) {
                JSONArray accounts = new JSONArray(response.body());
                System.out.println("Accounts retrieved successfully:");
                for (int i = 0; i < accounts.length(); i++) {
                    JSONObject account = accounts.getJSONObject(i);
                    System.out.println("  - " + account.getString("name") + 
                        " (ID: " + account.getString("id") + ")");
                }
            } else {
                System.err.println("Error " + response.statusCode() + ": " + 
                    response.body());
            }
            
        } catch (Exception e) {
            System.err.println("Error: " + e.getMessage());
        }
    }
}
using System;
using System.Net.Http;
using System.Threading.Tasks;

class Program
{
    static async Task Main(string[] args)
    {
        // Configuration
        string baseUrl = "https://demo.one.digicert.com";
        string adminApiKey = "ADMIN_API_KEY";
        
        // Get accounts
        using var client = new HttpClient();
        client.DefaultRequestHeaders.Add("x-api-key", adminApiKey);
        client.DefaultRequestHeaders.Add("Content-Type", "application/json");
        
        var response = await client.GetAsync(
            $"{baseUrl}/account/api/v1/account"
        );
        
        string responseBody = await response.Content.ReadAsStringAsync();
        Console.WriteLine($"Status Code: {(int)response.StatusCode}");
        Console.WriteLine(responseBody);
    }
}

Successful response (200 OK):

[
  {
    "id": "50580ac7-60e4-4df2-a834-d12c1ab79afb",
    "name": "Example account 1",
    "active": true,
    "service_period": {
      "from": "2021-05-25",
      "to": "2022-05-25"
    },
    "friendly_identifier": "5258283",
    "admins": [
      {
        "id": "833e4906-fc45-4bd3-841e-40506c0e8ca8",
        "email": "api_service_user_1@example.com"
      },
      {
        "id": "fa8285c7-5e35-4ea8-8cc4-dc95f7dc3cd6",
        "email": "api_service_user_2@example.com"
      },
      {
        "id": "7d78b46a-c635-4bda-8b6d-13802046a963",
        "name": "John Doe",
        "email": "account_user_1@example.com"
      }
    ],
    "sign_in_methods": [
      {
        "signInMethod": "standard",
        "status": "enabled",
        "mfaStatus": "disabled",
        "clientAuthCertLoginEnabled": false
      }
    ],
    "locale": "en_US"
  },
  {
    "id": "be5ffbd2-1a50-4675-912f-2fe015812f87",
    "name": "Example account 2",
    "active": true,
    "service_period": {
      "from": "2021-05-26",
      "to": "2022-05-26"
    },
    "friendly_identifier": "7092363",
    "admins": [],
    "sign_in_methods": [
      {
        "signInMethod": "standard",
        "status": "enabled",
        "mfaStatus": "disabled",
        "clientAuthCertLoginEnabled": false
      }
    ],
    "locale": "en_US"
  }
]

From the returned list of accounts, choose the account you want to work with and save its id value. You will need this in Step 3 when you create the service user.

Step 2: View available roles and permissions

Before creating a service user, you need to understand which roles are available in your account. Roles determine what a user (service user in this case) can see and do via the API.

The /account/api/v1/role endpoint returns all roles (default and custom) and are organized by manager.

Request:

curl -X GET https://demo.one.digicert.com/account/api/v1/role \
  -H "x-api-key: SERVICE_API_TOKEN" \
  -H "Content-Type: application/json" | jq '.'
import requests

# Configuration
BASE_URL = "https://demo.one.digicert.com"
SERVICE_API_TOKEN = "SERVICE_API_TOKEN"

# Get user roles
response = requests.get(
    f"{BASE_URL}/account/api/v1/role",
    headers={
        "x-api-key": SERVICE_API_TOKEN,
        "Content-Type": "application/json"
    }
)

print(f"Status Code: {response.status_code}")
print(response.json())
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;

public class Example {
    public static void main(String[] args) throws Exception {
        // Configuration
        String baseUrl = "https://demo.one.digicert.com";
        String serviceApiToken = "SERVICE_API_TOKEN";
        
        // Get user roles
        HttpClient client = HttpClient.newHttpClient();
        HttpRequest request = HttpRequest.newBuilder()
            .uri(URI.create(baseUrl + "/account/api/v1/role"))
            .header("x-api-key", serviceApiToken)
            .header("Content-Type", "application/json")
            .GET()
            .build();
        
        HttpResponse<String> response = client.send(
            request, 
            HttpResponse.BodyHandlers.ofString()
        );
        
        System.out.println("Status Code: " + response.statusCode());
        System.out.println(response.body());
    }
}
using System;
using System.Net.Http;
using System.Threading.Tasks;

class Program
{
    static async Task Main(string[] args)
    {
        // Configuration
        string baseUrl = "https://demo.one.digicert.com";
        string serviceApiToken = "SERVICE_API_TOKEN";
        
        // Get user roles
        using var client = new HttpClient();
        client.DefaultRequestHeaders.Add("x-api-key", serviceApiToken);
        client.DefaultRequestHeaders.Add("Content-Type", "application/json");
        
        var response = await client.GetAsync(
            $"{baseUrl}/account/api/v1/role"
        );
        
        string responseBody = await response.Content.ReadAsStringAsync();
        Console.WriteLine($"Status Code: {(int)response.StatusCode}");
        Console.WriteLine(responseBody);
    }
}

Successful response (200 OK):

{
  "ca_manager": [
    {
      "name": "CM_PKI_MANAGER",
      "display_name": "CM PKI MANAGER",
      "description": "Role with CM view permissions",
      "type": "default",
      "status": "ACTIVE",
      "access_scope": "account"
    },
    {
      "name": "CM_KEY_ESCROW",
      "display_name": "Key Escrow",
      "description": "CM Key Escrow",
      "type": "default",
      "status": "ACTIVE",
      "access_scope": "account"
    }
  ],
  "account_manager": [
    {
      "name": "AM_ACCOUNT_ADMIN",
      "display_name": "AM ACCOUNT ADMIN",
      "description": "Admin role with view and manage permissions",
      "type": "default",
      "status": "ACTIVE",
      "access_scope": "account"
    },
    {
      "name": "AM_DEFAULT_USER",
      "display_name": "AM DEFAULT USER",
      "description": "Default role with view permissions",
      "type": "default",
      "status": "ACTIVE",
      "access_scope": "account"
    },
    {
      "name": "AM_ACCOUNT_USER",
      "display_name": "AM ACCOUNT USER",
      "description": "Role with view permissions",
      "type": "default",
      "status": "ACTIVE",
      "access_scope": "account"
    },
    {
      "name": "AM_ACCOUNT_MANAGER",
      "display_name": "Account manager",
      "description": "AM Account manager",
      "type": "default",
      "status": "ACTIVE",
      "access_scope": "account"
    },
    {
      "name": "AM_USER_MANAGER",
      "display_name": "User manager",
      "description": "AM User manager",
      "type": "default",
      "status": "ACTIVE",
      "access_scope": "account"
    },
    {
      "name": "AM_VIEW_ONLY",
      "display_name": "View only",
      "description": "AM View only",
      "type": "default",
      "status": "ACTIVE",
      "access_scope": "account"
    }
  ],
  "secure_software_manager": [
    {
      "name": "SSM_KEYLOCKER_ADMIN",
      "display_name": "SSM KEYLOCKER ADMIN",
      "description": "Admin role with view and manage SSM permissions",
      "type": "default",
      "status": "ACTIVE",
      "access_scope": "account"
    },
    {
      "name": "SSM_KEYLOCKER_USER",
      "display_name": "SSM KEYLOCKER USER",
      "description": "Admin lite role",
      "type": "default",
      "status": "ACTIVE",
      "access_scope": "account"
    },
    {
      "name": "SSM_LEAD",
      "display_name": "SSM Lead",
      "description": "SSM Lead",
      "type": "default",
      "status": "ACTIVE",
      "access_scope": "account"
    },
    {
      "name": "SSM_DEVELOPER",
      "display_name": "SSM Developer",
      "description": "SSM Developer",
      "type": "default",
      "status": "ACTIVE",
      "access_scope": "account"
    },
    {
      "name": "SSM_TEAM_LEAD",
      "display_name": "SSM Team Lead",
      "description": "SSM Team Lead",
      "type": "default",
      "status": "ACTIVE",
      "access_scope": "account"
    },
    {
      "name": "SSM_SIGNER",
      "display_name": "SSM Signer",
      "description": "SSM Signer",
      "type": "default",
      "status": "ACTIVE",
      "access_scope": "account"
    }
  ],
  "enterprise_manager": [
    {
      "name": "EM_EPKI_ACCOUNT_MANAGER",
      "display_name": "EPKI Account Manager",
      "description": "EPKI Account Manager",
      "type": "default",
      "status": "ACTIVE",
      "access_scope": "account"
    },
    {
      "name": "EM_EPKI_RECOVERY_MANAGER",
      "display_name": "EPKI Recovery Manager",
      "description": "EPKI Recovery Manager",
      "type": "default",
      "status": "ACTIVE",
      "access_scope": "account"
    },
    {
      "name": "EM_EPKI_IMPORT_MANAGER",
      "display_name": "EPKI Import Manager",
      "description": "EPKI Import Manager",
      "type": "default",
      "status": "ACTIVE",
      "access_scope": "account"
    },
    {
      "name": "EM_EPKI_USER_&_CERT_MANAGER",
      "display_name": "EPKI User & cert manager",
      "description": "EPKI User & cert manager",
      "type": "default",
      "status": "ACTIVE",
      "access_scope": "account"
    },
    {
      "name": "EM_EPKI_CERT_PROFILE_MANAGER",
      "display_name": "EPKI Cert Profile Manager",
      "description": "EPKI Cert Profile Manager",
      "type": "default",
      "status": "ACTIVE",
      "access_scope": "account"
    }
  ],
  "device_manager": [
    {
      "name": "IOT_CUSTOM_ROLE",
      "display_name": "Custom role",
      "description": "Custom role description.",
      "type": "custom",
      "status": "ACTIVE",
      "access_scope": "account"
    },
    {
      "name": "IOT_ACCOUNT_MANAGER",
      "display_name": "IOT Account Manager",
      "description": "IOT Account Manager",
      "type": "default",
      "status": "ACTIVE",
      "access_scope": "account"
    }
  ],
  "document_signing_manager": [
    {
      "name": "DSM_DOCUMENT_SIGNER",
      "display_name": "DSM DOCUMENT SIGNER",
      "description": "Role with signer permissions",
      "type": "default",
      "status": "ACTIVE",
      "access_scope": "account"
    },
    {
      "name": "DSM_CLIENT_ADMIN",
      "display_name": "DSM Client Admin",
      "description": "DSM Client Admin",
      "type": "default",
      "status": "ACTIVE",
      "access_scope": "account"
    },
    {
      "name": "DSM_SIGNER",
      "display_name": "DSM Signer",
      "description": "DSM Signer",
      "type": "default",
      "status": "ACTIVE",
      "access_scope": "account"
    }
  ]
}

The response body returns a list of user roles for your account. By default, it returns all roles (both default system roles and custom roles) for your primary account, organized by manager.

  • account_manager: Account manager
  • ca_manager: DigiCert® Private CA
  • enterprise_manager: Trust Lifecycle
  • device_trust_manager: Device Trust
  • secure_software_manager: Software Trust
  • document_signing_manager: Document Trust
  • device_manager: IoT Trust

Each role object in the response contains these fields:

  • name: The role identifier used in API requests.
  • display_name: Friendly role name
  • description: What the role allows users to do
  • type: Whether it’s a default system role or custom role
  • status: Whether the role is ACTIVE or ARCHIVED

When you create a service user in the next step, you’ll specify which roles to assign using the role name, such as AM_DEFAULT_USER.

Step 3: Create the service user

Service users require four fields in the request body:

  • friendly_name to identify the service user.
  • email_address for notifications.
  • account_id for association.
  • roles for permissions and manager access.

After gathering those details, make a POST request to the /account/api/v1/user endpoint.

Request:

curl -X POST \
  https://demo.one.digicert.com/account/api/v1/user \
  -H "x-api-key: ADMIN_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "friendly_name": "API Integration Service User",
    "email": "api-notifications@example.com",
    "description": "Service user for certificate automation",
    "accounts": ["YOUR_ACCOUNT_ID"],
    "roles": ["AM_DEFAULT_USER"]
  }'
import requests

# Configuration
BASE_URL = "https://demo.one.digicert.com"
ADMIN_API_TOKEN = "ADMIN_API_TOKEN"
# User details
FRIENDLY_NAME = "API Integration Service User"
EMAIL = "api-notifications@example.com"
DESCRIPTION = "Service user for certificate automation"
ACCOUNT_ID = "ACCOUNT_ID"

# Create service user
payload = {
    "friendly_name": FRIENDLY_NAME,
    "email": EMAIL,
    "description": DESCRIPTION,
    "accounts": [ACCOUNT_ID],
    "roles": ["AM_DEFAULT_USER"]
}

response = requests.post(
    f"{BASE_URL}/account/api/v1/user",
    headers={
        "x-api-key": ADMIN_API_TOKEN,
        "Content-Type": "application/json"
    },
    json=payload
)

print(f"Status Code: {response.status_code}")
print(response.json())
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ObjectNode;
import com.fasterxml.jackson.databind.node.ArrayNode;

public class Example {
    public static void main(String[] args) throws Exception {
        // Configuration
        String baseUrl = "https://demo.one.digicert.com";
        String adminApiToken = "ADMIN_API_TOKEN";
        // User details
        String friendlyName = "API Integration Service User";
        String email = "api-notifications@example.com";
        String description = "Service user for certificate automation";
        String accountId = "ACCOUNT_ID";
        
        // Build JSON payload
        ObjectMapper mapper = new ObjectMapper();
        ObjectNode payload = mapper.createObjectNode();
        payload.put("friendly_name", friendlyName);
        payload.put("email", email);
        payload.put("description", description);
        
        ArrayNode accounts = mapper.createArrayNode();
        accounts.add(accountId);
        payload.set("accounts", accounts);
        
        ArrayNode roles = mapper.createArrayNode();
        roles.add("AM_DEFAULT_USER");
        payload.set("roles", roles);
        
        // Create service user
        HttpClient client = HttpClient.newHttpClient();
        HttpRequest request = HttpRequest.newBuilder()
            .uri(URI.create(baseUrl + "/account/api/v1/user"))
            .header("x-api-key", adminApiToken)
            .header("Content-Type", "application/json")
            .POST(HttpRequest.BodyPublishers.ofString(mapper.writeValueAsString(payload)))
            .build();
        
        HttpResponse<String> response = client.send(
            request, 
            HttpResponse.BodyHandlers.ofString()
        );
        
        System.out.println("Status Code: " + response.statusCode());
        System.out.println(response.body());
    }
}
using System;
using System.Net.Http;
using System.Text;
using System.Text.Json;
using System.Text.Json.Nodes;
using System.Threading.Tasks;

class Program
{
    static async Task Main(string[] args)
    {
        // Configuration
        string baseUrl = "https://demo.one.digicert.com";
        string adminApiToken = "ADMIN_API_TOKEN";
        // User details
        string friendlyName = "API Integration Service User";
        string email = "api-notifications@example.com";
        string description = "Service user for certificate automation";
        string accountId = "ACCOUNT_ID";
        
        // Build JSON payload
        var payload = new JsonObject
        {
            ["friendly_name"] = friendlyName,
            ["email"] = email,
            ["description"] = description,
            ["accounts"] = new JsonArray { accountId },
            ["roles"] = new JsonArray { "AM_DEFAULT_USER" }
        };
        
        // Create service user
        using var client = new HttpClient();
        client.DefaultRequestHeaders.Add("x-api-key", adminApiToken);
        
        var content = new StringContent(
            payload.ToJsonString(), 
            Encoding.UTF8, 
            "application/json"
        );
        
        var response = await client.PostAsync(
            $"{baseUrl}/account/api/v1/user",
            content
        );
        
        string responseBody = await response.Content.ReadAsStringAsync();
        Console.WriteLine($"Status Code: {(int)response.StatusCode}");
        Console.WriteLine(responseBody);
    }
}

Successful response (200 OK):

{
  "id": "5e0bd5fe-117f-4049-b686-1548b1ee5e14",
  "email": "api-notifications@example.com",
  "status": "ACTIVE",
  "access_scope": "account",
  "primary_account_id": "449922b5-aad9-4e5b-9025-2bd0daf3619e",
  "created_at": "2025-10-15T15:40:20Z",
  "friendly_name": "API Integration Service User",
  "description": "Service user for certificate automation",
  "api_token": {
    "id": "cdfcf47d-b47f-4919-bd1b-c62935312cea",
    "user_id": "5e0bd5fe-117f-4049-b686-1548b1ee5e14",
    "name": "API Integration Service User",
    "token": "bedda3cd381bdfc8b17e10a0bfe350340cc4502c4ea9f41c3230ca6f8a17e97b7faa180727952e31fa1fe3227b2",
    "enabled": true
  },
  "accounts": [
    {
      "id": "449922b5-aad9-4e5b-9025-2bd0daf3619e",
      "name": "Demo Account",
      "active": true
    }
  ],
  "applications": [
    {
      "id": "68e8e9fa-01cf-468f-9aae-f8b3b915f9c3",
      "name": "Account Manager",
      "permissions": ["VIEW_AM_ACCOUNT", "VIEW_AM_USER"]
    }
  ]
}

Step 4: Make your first authenticated request

Test the service user’s access by using the /account/api/v1/user/me endpoint.

Request:

curl -X GET https://demo.one.digicert.com/account/api/v1/user/me \
  -H "x-api-key: SERVICE_API_TOKEN" \
  -H "Content-Type: application/json" | jq '.'
import requests

# Configuration
BASE_URL = "https://demo.one.digicert.com"
SERVICE_API_TOKEN = "SERVICE_API_TOKEN"

# Get current user details
response = requests.get(
    f"{BASE_URL}/account/api/v1/user/me",
    headers={
        "x-api-key": SERVICE_API_TOKEN,
        "Content-Type": "application/json"
    }
)

print(f"Status Code: {response.status_code}")
print(response.json())
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;

public class Example {
    public static void main(String[] args) throws Exception {
        // Configuration
        String baseUrl = "https://demo.one.digicert.com";
        String serviceApiToken = "SERVICE_API_TOKEN";
        
        // Get current user details
        HttpClient client = HttpClient.newHttpClient();
        HttpRequest request = HttpRequest.newBuilder()
            .uri(URI.create(baseUrl + "/account/api/v1/user/me"))
            .header("x-api-key", serviceApiToken)
            .header("Content-Type", "application/json")
            .GET()
            .build();
        
        HttpResponse<String> response = client.send(
            request, 
            HttpResponse.BodyHandlers.ofString()
        );
        
        System.out.println("Status Code: " + response.statusCode());
        System.out.println(response.body());
    }
}
using System;
using System.Net.Http;
using System.Threading.Tasks;

class Program
{
    static async Task Main(string[] args)
    {
        // Configuration
        string baseUrl = "https://demo.one.digicert.com";
        string serviceApiToken = "SERVICE_API_TOKEN";
        
        // Get current user details
        using var client = new HttpClient();
        client.DefaultRequestHeaders.Add("x-api-key", serviceApiToken);
        client.DefaultRequestHeaders.Add("Content-Type", "application/json");
        
        var response = await client.GetAsync(
            $"{baseUrl}/account/api/v1/user/me"
        );
        
        string responseBody = await response.Content.ReadAsStringAsync();
        Console.WriteLine($"Status Code: {(int)response.StatusCode}");
        Console.WriteLine(responseBody);
    }
}

Common errors and solutions

{
    "errors": [
        {
            "code": "AUTHORIZATION_ERROR",
            "message": "No authentication data provided"
        }
    ]
}

Make sure you include a valid API token with your request using the `x-api-key` header.
{
    "errors": [
        {
            "code": "no_access",
            "message": "Not enough permissions"
        }
    ]
}

Make sure your API token has appropriate roles and permissions.
{
    "errors": [
        {
            "code": "invalid_input_field",
            "message": "Wrong input or input format"
        }
    ]
}

Check endpoint specifications for valid field values.

Check your request body and validate your JSON.
{
    "errors": [
        {
            "code": "duplicate_error",
            "message": "Nickname [name] already exists. Enter a different nickname."
        }
    ]
}

Use a different value for the specified field.

What’s next?