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/{user_id}GETGet details about a 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_TOKEN" | jq '.'
import requests

# Configuration
BASE_URL = "https://demo.one.digicert.com"
ADMIN_API_TOKEN = "ADMIN_API_TOKEN"
response = requests.get(
    f"{BASE_URL}/account/api/v1/account",
    headers={"x-api-key": ADMIN_API_TOKEN}
)

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 ApiExample {
    public static void main(String[] args) throws Exception {
        // Configuration
        String baseUrl = "https://demo.one.digicert.com";
        String adminApiToken = "ADMIN_API_TOKEN";

        // Send request
        HttpClient client = HttpClient.newHttpClient();
        HttpRequest request = HttpRequest.newBuilder()
            .uri(URI.create(baseUrl + "/account/api/v1/account"))
            .header("x-api-key", adminApiToken)
            .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 adminApiToken = "ADMIN_API_TOKEN";

        // Send request
        using var client = new HttpClient();
        client.DefaultRequestHeaders.Add("x-api-key", adminApiToken);
        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" | jq '.'
import requests

# Configuration
BASE_URL = "https://demo.one.digicert.com"
SERVICE_API_TOKEN = "SERVICE_API_TOKEN"
response = requests.get(
    f"{BASE_URL}/account/api/v1/role",
    headers={"x-api-key": SERVICE_API_TOKEN}
)

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 ApiExample {
    public static void main(String[] args) throws Exception {
        // Configuration
        String baseUrl = "https://demo.one.digicert.com";
        String serviceApiToken = "SERVICE_API_TOKEN";

        // Send request
        HttpClient client = HttpClient.newHttpClient();
        HttpRequest request = HttpRequest.newBuilder()
            .uri(URI.create(baseUrl + "/account/api/v1/role"))
            .header("x-api-key", serviceApiToken)
            .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";

        // Send request
        using var client = new HttpClient();
        client.DefaultRequestHeaders.Add("x-api-key", serviceApiToken);
        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_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "friendly_name": "Service User Friendly Name",
    "email": "jane@example.com",
    "description": "Service user description",
    "roles": [
      "AM_ACCOUNT_ADMIN"
    ],
    "accounts": [
      "ACCOUNTS"
    ]
  }' | jq '.'
import requests

# Configuration
BASE_URL = "https://demo.one.digicert.com"
ADMIN_API_TOKEN = "ADMIN_API_TOKEN"
# Request details
FRIENDLY_NAME = "Service User Friendly Name"
EMAIL = "jane@example.com"
DESCRIPTION = "Service user description"
ACCOUNTS = "ACCOUNTS"
AM_ACCOUNT_ADMIN = "AM_ACCOUNT_ADMIN"

payload = {
    "friendly_name": FRIENDLY_NAME,
    "email": EMAIL,
    "description": DESCRIPTION,
    "accounts": [ACCOUNTS],
    "roles": [AM_ACCOUNT_ADMIN],
}

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 ApiExample {
    public static void main(String[] args) throws Exception {
        // Configuration
        String baseUrl = "https://demo.one.digicert.com";
        String adminApiToken = "ADMIN_API_TOKEN";
        // Request details
        String friendlyName = "Service User Friendly Name";
        String email = "jane@example.com";
        String description = "Service user description";

        // Build payload
        ObjectMapper mapper = new ObjectMapper();
        ObjectNode payload = mapper.createObjectNode();
        payload.put("friendly_name", friendlyName);
        payload.put("email", email);
        payload.put("description", description);

        ArrayNode accountsArray = mapper.createArrayNode();
        accountsArray.add("ACCOUNTS");
        payload.set("accounts", accountsArray);

        ArrayNode rolesArray = mapper.createArrayNode();
        rolesArray.add("AM_ACCOUNT_ADMIN");
        payload.set("roles", rolesArray);

        // Send request
        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.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";
        // Request details
        string friendlyName = "Service User Friendly Name";
        string email = "jane@example.com";
        string description = "Service user description";

        // Build payload
        var payload = new JsonObject
        {
            ["friendly_name"] = friendlyName,
            ["email"] = email,
            ["description"] = description,
            ["accounts"] = new JsonArray { "ACCOUNTS" },
            ["roles"] = new JsonArray { "AM_ACCOUNT_ADMIN" }
        };

        // Send request
        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/{user_id} endpoint. Replace {user_id} with the service user ID returned in Step 3.

Request:

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

# Configuration
BASE_URL = "https://demo.one.digicert.com"
SERVICE_API_TOKEN = "SERVICE_API_TOKEN"
USER_ID = "USER_ID"
response = requests.get(
    f"{BASE_URL}/account/api/v1/user/{USER_ID}",
    headers={"x-api-key": SERVICE_API_TOKEN}
)

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 ApiExample {
    public static void main(String[] args) throws Exception {
        // Configuration
        String baseUrl = "https://demo.one.digicert.com";
        String serviceApiToken = "SERVICE_API_TOKEN";
        String userId = "USER_ID";

        // Send request
        HttpClient client = HttpClient.newHttpClient();
        HttpRequest request = HttpRequest.newBuilder()
            .uri(URI.create(baseUrl + "/account/api/v1/user/" + userId))
            .header("x-api-key", serviceApiToken)
            .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";
        string userId = "USER_ID";

        // Send request
        using var client = new HttpClient();
        client.DefaultRequestHeaders.Add("x-api-key", serviceApiToken);
        var response = await client.GetAsync($"{baseUrl}/account/api/v1/user/{userId}");

        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?