Skip to main content

Command Palette

Search for a command to run...

CyberArk API: The Complete Guide

Master CyberArk API and develop scripts and set-up automations for PAM Administration

Updated
14 min read
D
CyberArk PAM Specialist with 3+ years’ experience in delivering secure, reliable Privileged Access Management (PAM) and Identity & Access Management (IAM) solutions. Skilled in end-to-end CyberArk implementations, upgrades, and migrations, with deep expertise in architecture design, SIEM integration, Linux platform administration, and authentication deployment. Passionate about optimizing PAM environments for performance, scalability, and compliance in high-reliability settings. Certified Delivery Engineer (CDE-PAM), Defender (PAM-DEF), Sentry (PAM-SEN). Always open to collaborating on projects that strengthen enterprise security posture and enable digital trust.

CyberArk APIs for PAM

CyberArk exposes REST APIs for PAM Self‑Hosted (CorePAS) and Privilege Cloud that let you automate almost everything you can do via the web UI: manage safes, accounts, platforms, and passwords, all over HTTPS+JSON.
Both products use the same URL pattern under …/PasswordVault/ and the same Safe‑level permissions (List/Use/Retrieve, Add accounts, Manage Safe, etc.), so most scripts can be ported between self‑hosted and cloud with minor changes.


Self‑Hosted vs Privilege Cloud: What changes, What doesn’t

PAM – Self‑Hosted hosts PVWA (and thus the REST API) on your own infrastructure with a base like https://pvwa.company.com/PasswordVault, while Privilege Cloud exposes the same APIs via a SaaS portal like https://<tenant>.privilegecloud.cyberark.com/PasswordVault.
The API resources (Safes, Accounts, Auth, etc.) and permission flags (listAccounts, retrieveAccounts, manageSafe, …) are fundamentally the same in both; the main differences are identity source (Vault/LDAP vs. CyberArk Identity) and who manages platform upgrades.


Core permission model: Vault vs Safe permissions

CyberArk authorization for API calls is a combination of Vault‑level permissions (for example, “Add Safes”, “Manage Safe Members” at the Vault level) and Safe membership permissions (List/Use/Retrieve accounts, Add accounts, Manage Safe, etc.).
The Safe‑member permission object (used by the Update Safe member REST API) lists booleans such as useAccounts, retrieveAccounts, listAccounts, addAccounts, updateAccountContent, manageSafe, and manageSafeMembers, and these control what your API user can do in that Safe.


Safe permissions: List, Use, Retrieve (you will use these a lot)

CyberArk documentation and training material explain that:

  • List accounts (listAccounts) lets a member see the list of accounts in a Safe and view account objects.

  • Use accounts (useAccounts) lets the member use accounts via PSM without viewing the password.

  • Retrieve accounts (retrieveAccounts) lets the member retrieve/show/copy the password value.

Official and community sources clarify that you can technically grant Retrieve without List, but then the user cannot see accounts to select them; in practice you grant List + Retrieve (and optional Use) to accounts that need to see passwords.


Authentication & Sessions

Logon (self‑hosted and cloud)

Both PAM – Self‑Hosted and Privilege Cloud use a Logon endpoint under /PasswordVault/API/Auth/.../Logon that returns a session token; you then send that token in the Authorization header for all other calls.
For self‑hosted, common endpoints include /API/Auth/CyberArk/Logon (Vault/CyberArk directory), /API/Auth/LDAP/Logon, or /API/Auth/SAML/Logon; Privilege Cloud offers equivalent auth paths integrated with CyberArk Identity.

Permissions required (Logon):

  • A valid user account (local/LDAP/SAML/cloud) that is not disabled and has at least some Safe memberships.

  • No specific Safe permission is required for the Logon call itself, but the user’s later capabilities depend entirely on Safe and Vault permissions.

Python example (works for self‑hosted or cloud, just change BASE_URL and auth_path):

import requests

BASE_URL = "https://pvwa.example.com/PasswordVault"  # or Privilege Cloud URL
LOGON_URL = f"{BASE_URL}/API/Auth/CyberArk/Logon"    # change to /LDAP/Logon or /SAML/Logon if needed

def logon(username: str, password: str, verify_ssl: bool = True) -> str:
    payload = {
        "username": username,
        "password": password,
        "concurrentSession": True
    }
    resp = requests.post(LOGON_URL, json=payload, verify=verify_ssl)
    resp.raise_for_status()
    return resp.text.strip('"')  # token string

token = logon("api.user", "SuperSecret!")
headers = {"Authorization": token}

Logoff

You end the session with POST /PasswordVault/API/Auth/Logoff, which invalidates the token but does not require any extra Safe/Vault permission.
Any logged‑in user can log off their own session, and doing so is good practice in automation to scope tokens to the minimal time window.


Working with safes

Listing safes

PAM Self‑Hosted exposes “Get all Safes” and similar REST methods under /PasswordVault/API/Safes that return the subset of Safes where the caller has membership; there is no “see every Safe” unless you have broad admin rights.
Privilege Cloud follows the same pattern. List calls show only Safes where the user has permissions, as reinforced by training and admin scripts that iterate “all safes you have” then add members.

Permissions required (list safes / read safe info):

  • Membership in the Safe(s) to be returned; at minimum, some Safe permission such as List accounts or View Safe Members, depending on the method.

  • For admin‑style reporting of safes and members, use Vault admin or Safe admin accounts with viewSafeMembers and viewAuditLog where needed.

Python example:

with CyberArkClient("https://pvwa.example.com/PasswordVault",
                    username="api.user", password="SuperSecret!") as ca:
    safes = ca.get("/API/Safes")
    for safe in safes.get("value", []):
        print(safe["SafeName"], "-", safe.get("Description", ""))

Creating a safe

The Add Safe REST API is /PasswordVault/API/Safes (POST) for both self‑hosted and cloud, with a JSON body defining safeName, managingCPM, retention, OLAC, etc.
The doc explicitly states: “The user who runs this web service must have Add Safes permissions in the Vault.”

Permissions required (create safe):

  • Vault‑level Add Safes permission on the calling user.

  • No prior membership in the new Safe is required; the creator is recorded as creator.name in the result and typically becomes a Safe member with strong rights.

Python example:

def create_safe(ca: CyberArkClient, safe_name: str, description: str = "") -> dict:
    body = {
        "safeName": safe_name,
        "description": description,
        "managingCPM": "PasswordManager",
        "numberOfVersionsRetention": None,
        "numberOfDaysRetention": 7,
        "olacEnabled": False,
        "autoPurgeEnabled": True,
        "location": "\\"
    }
    return ca.post("/API/Safes", json_body=body)

with CyberArkClient("https://pvwa.example.com/PasswordVault",
                    username="vault.admin", password="AdminPass!") as ca:
    new_safe = create_safe(ca, "APP_Oracle", "Safe for Oracle app accounts")
    print(new_safe["safeName"], "created by", new_safe["creator"]["name"])

Managing safe members and their permissions

Adding or updating Safe members is done via /PasswordVault/API/Safes/{safeUrlId}/Members (POST/PUT); the Update Safe member doc shows a permissions object with flags like useAccounts, retrieveAccounts, listAccounts, addAccounts, manageSafe, and manageSafeMembers.
These endpoints are identical in self‑hosted and cloud (Privilege Cloud Shared Services docs show the same JSON), and a 403 often indicates that you tried to assign a permission you yourself don’t have.

Permissions required (add / update Safe members):

  • Vault‑level Manage Safe Members permission for the calling user.

  • In practice, you also usually have manageSafe on that Safe, but the docs highlight Manage Safe Members as the formal requirement.

Python example (grant an app ID List+Use+Retrieve on a Safe):

def add_safe_member(ca: CyberArkClient, safe_url_id: str, member_name: str) -> dict:
    body = {
        "memberName": member_name,
        "membershipExpirationDate": None,
        "permissions": {
            "useAccounts": True,
            "retrieveAccounts": True,
            "listAccounts": True,
            "addAccounts": False,
            "updateAccountContent": False,
            "updateAccountProperties": False,
            "initiateCPMAccountManagementOperations": False,
            "renameAccounts": False,
            "deleteAccounts": False,
            "unlockAccounts": False,
            "manageSafe": False,
            "manageSafeMembers": False,
            "backupSafe": False,
            "viewAuditLog": False,
            "viewSafeMembers": False,
            "accessWithoutConfirmation": False,
            "createFolders": False,
            "deleteFolders": False,
            "moveAccountsAndFolders": False,
            "requestsAuthorizationLevel1": False,
            "requestsAuthorizationLevel2": False
        }
    }
    return ca.post(f"/API/Safes/{safe_url_id}/Members", json_body=body)

Working with accounts

Listing and searching accounts

The core endpoint is GET /PasswordVault/API/Accounts, which lists accounts according to your Safe permissions and any filters you pass (Safe, platform, search terms, etc.).
Documentation and KBs on Privilege Cloud note that searches run across “all Safes in the Vault that you are authorized to access”, based on your Safe memberships.

Permissions required (list/search accounts):

  • On each Safe whose accounts you want to see: List accounts (listAccounts) permission.

  • Without listAccounts, you cannot see the accounts in UI or via REST, even if you technically hold Retrieve; so for automation, assume you need List for every read.

Python example:

with CyberArkClient("https://pvwa.example.com/PasswordVault",
                    username="api.reader", password="ReaderPass!") as ca:
    # All accessible accounts (may be large; filter in real code)
    accounts = ca.get("/API/Accounts")
    print("Total visible accounts:", accounts.get("Count"))

    # Filter by Safe name
    prod_accounts = ca.get("/API/Accounts", params={"Safe": "APP_Oracle"})
    for a in prod_accounts.get("value", []):
        print(a["id"], a["name"], a["safeName"])

Getting account details

To fetch specific account metadata, you call GET /PasswordVault/API/Accounts/{id} for that ID.
This returns JSON with properties such as name, address, userName, platformId, and Safe, but not usually the raw password value.

Permissions required (get account details):

  • On the account’s Safe: List accounts permission.

  • OLAC (Object Level Access Control) and additional policies may further restrict access, but listAccounts is the basic requirement.


Creating accounts

The account creation endpoint is typically POST /PasswordVault/API/Accounts, with a body defining Safe, platformId, address, userName, etc.
This is how you onboard credentials programmatically when building app onboarding or migration tooling.

Permissions required (create/add accounts):

  • On the target Safe: Add accounts (addAccounts) permission; CyberArk docs note that Add accounts automatically grants Update account properties as well.

  • listAccounts is frequently also present so the user can see what they’ve created, but strictly speaking Add is the creation permission.


Updating account properties and password content

There are separate permissions for Update account properties and Update account content, plus Initiate CPM account management operations for triggering CPM flows such as change/verify.
Using the REST APIs you can, for example, change metadata like platform or address (properties) or manually set a password value (content), depending on your platform and policy.

Permissions required:

  • Update account properties (updateAccountProperties) on the Safe to change metadata fields.

  • Update account content (updateAccountContent) for direct value changes, and Initiate CPM account management operations to tell CPM to rotate or verify.


Retrieving passwords

The canonical password retrieval endpoint in modern REST APIs is POST /PasswordVault/API/Accounts/{id}/Password/Retrieve (and related GetPasswordValue methods).
Docs and KBs for Privilege Cloud explicitly say that users with Retrieve accounts and List accounts authorizations “can view the accounts and their credentials”, and integrating tools like Tines/Axonius call this same endpoint.

Permissions required (retrieve password):

  • On the account’s Safe: Retrieve accounts (retrieveAccounts) permission to see/copy the password.

  • In practice, also List accounts so your script can discover the account and navigate to it.

Python example (self‑hosted or cloud):

def retrieve_password(ca: CyberArkClient, account_id: str) -> str:
    path = f"/API/Accounts/{account_id}/Password/Retrieve"
    resp = ca.post(path, json_body={})  # body often empty or with optional params

    # Many deployments return JSON with 'Content'; others return raw text
    if isinstance(resp, dict) and "Content" in resp:
        return resp["Content"]
    if isinstance(resp, str):
        return resp
    raise ValueError(f"Unexpected password response: {resp}")

with CyberArkClient("https://tenant.privilegecloud.cyberark.com/PasswordVault",
                    username="app.id", password="ApiKeyOrPassword") as ca:
    pw = retrieve_password(ca, "123_4")  # example AccountID
    # Use pw in memory only; do not log or persist it.

Deleting and unlocking accounts

You can delete accounts via DELETE /PasswordVault/API/Accounts/{id} and unlock them using dedicated “unlock” endpoints/flags in the REST API.
The Safe‑member permission object includes deleteAccounts and unlockAccounts flags for these operations.

Permissions required:

  • Delete accounts (deleteAccounts) on the Safe to remove account objects.

  • Unlock accounts (unlockAccounts) to clear lock state; typically granted to Safe admins rather than general users.


Platforms and REST‑based CPM plugins

CyberArk’s REST API application plugin framework allows CPM to manage target systems purely via REST calls defined in a configuration file, with the CPM plugin DLLs interpreting those definitions.
The framework supports GET/POST/PUT/DELETE/PATCH, can reference platform and account parameters, and includes options for JSON/XML/text parsing and masking of sensitive data.

Permissions required (creating/editing platforms and plugins):

  • Platform or Vault admin roles, with Safe membership on internal system Safes such as PasswordManager where platform definitions are stored.

  • For manipulating the Safes themselves, you also need Manage Safe and sometimes Backup Safe and View audit log on those system Safes.


Error handling and HTTP status codes

The PAM REST docs for both self‑hosted and Privilege Cloud enumerate HTTP status codes and error formats; 2xx indicates success, 4xx and 5xx return JSON describing the problem (for example, unauthorized, forbidden, not found).
A common pattern is: 401 when the token is missing/invalid; 403 when the user lacks required Safe/Vault permissions; 404 when an ID is wrong or the user has no access to that resource.

Permissions aspect:

  • If you see 403 while adding Safe members or changing permissions, docs highlight two main causes: trying to assign a permission you yourself don’t have or trying to change your own permissions on the Safe.

  • If you see an empty or partial list of Safes/accounts, it’s usually because the API user lacks membership or listAccounts in some Safes you expected to see.


Discovering APIs via Swagger

Privilege Cloud provides Swagger at https://<tenant>.privilegecloud.cyberark.com/PasswordVault/Swagger/, listing all REST operations available to your tenant and their schemas.
Supported self‑hosted versions expose a similar Swagger endpoint via PVWA when enabled, which is the most accurate way to see which APIs and models exist in your deployment.

Permissions aspect:

  • Swagger visibility mainly depends on PVWA access, but actual “Try it out” calls run with your session’s Safe/Vault permissions; you’ll only see/modify what you’re allowed to.

Security, least privilege, and design tips

Docs and KBs for Safe permissions emphasise using combinations of List/Use/Retrieve carefully: List+Use without Retrieve lets admins connect to targets without seeing passwords, while List+Use+Retrieve allows both connection and password viewing.
Many organizations separate “operations” users (List+Use), “break‑glass” users (List+Use+Retrieve), and Vault admins (Add Safes, Manage Safe/Members) to avoid central admin accounts seeing every password by default.

When designing API users:

  • Create dedicated service accounts per integration (for example, svc_app_onboarding, svc_ticket_sync) and give each only the Safes and permissions needed (Add accounts vs. Retrieve, etc.).

  • Avoid giving Vault‑wide Add Safes or Manage Safe Members unless you are automating safe provisioning at scale; even then, restrict what templates and groups the script can apply.


Example end‑to‑end flow with permissions (Self‑Hosted)

Goal: onboard a new application with its own Safe and a service account, and allow an app ID to retrieve passwords.

Steps and required permissions:

  1. Create Safe APP_Oracle

    • API call: POST /API/Safes (Add Safe).

    • Permissions needed: Vault‑level Add Safes on the caller.

  2. Add application group/user as Safe member

    • API call: POST /API/Safes/APP_Oracle/Members.

    • Permissions needed: Vault‑level Manage Safe Members on the caller; set member permissions to at least listAccounts + retrieveAccounts (and optionally useAccounts).

  3. Onboard the Oracle account into the Safe

    • API call: POST /API/Accounts specifying Safe=APP_Oracle.

    • Permissions needed: On APP_Oracle, the caller must have Add accounts (and implicitly gets Update account properties).

  4. App retrieves password at runtime

    • API logon: app ID calls /API/Auth/.../Logon, then POST /API/Accounts/{id}/Password/Retrieve.

    • Permissions needed: On APP_Oracle, app ID Safe member must have List accounts + Retrieve accounts (and useAccounts if you also run PSM sessions).

This same pattern works in Privilege Cloud; swap the base URL to your tenant and ensure the identities and groups you reference exist in CyberArk Identity / your cloud directory.


Quick permission cheat sheet (for developers)

You can pin this table next to your IDE when writing CyberArk automation:

Operation you call Minimal permissions your API user needs
Logon / Logoff Valid CyberArk user; no special Safe permission for the call itself.
List or search accounts (GET /API/Accounts) listAccounts on each Safe whose accounts you need to see.
Get account details (GET /API/Accounts/{id}) listAccounts on that Safe.
Retrieve password (POST /API/Accounts/{id}/Password/Retrieve) retrieveAccounts (and practically listAccounts) on that Safe.
Use account via PSM (no password view) useAccounts + listAccounts on that Safe.
Create account (POST /API/Accounts) addAccounts on target Safe (gives updateAccountProperties as well).
Change password / value updateAccountContent and often initiateCPMAccountManagementOperations.
Update account properties updateAccountProperties on that Safe.
Delete or unlock account deleteAccounts or unlockAccounts respectively on that Safe.
Create Safe (POST /API/Safes) Vault‑level Add Safes.
Add/update Safe members Vault‑level Manage Safe Members.
Change Safe settings manageSafe on that Safe (plus any Vault admin role as required).
View Safe members / audit viewSafeMembers / viewAuditLog on that Safe.

If you wire your Python client around these permission rules and consciously scope what each service user can do, you’ll have a CyberArk API layer that is both powerful and aligned with least‑privilege best practices in PAM Self‑Hosted and in Privilege Cloud.