ERS API Reference

Overview

The External RESTful Services (ERS) API provides configuration CRUD operations for ISE resources. With 199 endpoints across 70 resource types, ERS is the primary API for automation and integration.

Base URL

ise-01.inside.domusdigitalis.dev:9060/ers/config

Port

9060 (HTTPS)

Authentication

HTTP Basic (ERS Admin role required)

Content-Type

application/json (recommended) or application/xml

Pagination

?page=1&size=100 (max 100 per page)

Setup

# Load credentials
dsource d000 dev/network

# ERS API configuration
ISE_HOST="${ISE_PAN_IP}"
ISE_PORT="9060"
ISE_AUTH="${ISE_API_USER}:${ISE_API_PASS}"
BASE_URL="https://${ISE_HOST}:${ISE_PORT}/ers/config"

Authentication

Authentication Required

ISE ERS and OpenAPI use HTTP Basic Authentication. Credentials must have ERS Admin role enabled in ISE Administration > System > Admin Access > Administrators.

# Load credentials from secrets manager
dsource d000 dev/network

# Credentials available as environment variables:
#   ISE_API_USER - Username with ERS Admin role
#   ISE_API_PASS - Password

Resource Categories

Identity Management

Resource Endpoints netapi Description

Endpoints

5

MAC addresses representing network devices

Endpoint Groups

5

Logical groupings for policy assignment

Identity Groups

5

User identity groupings

Internal Users

5

Local user accounts

Guest Users

5

Temporary guest accounts

Network Devices

Resource Endpoints netapi Description

Network Devices

5

Switches, WLCs, routers (RADIUS clients)

Network Device Groups

5

Device groupings by location, type, etc.

Policy

Resource Endpoints netapi Description

Authorization Profiles

5

RADIUS attributes returned on success

Downloadable ACLs

5

dACLs pushed to network devices

Allowed Protocols

5

EAP method configurations

Conditions

5

Policy condition building blocks

TrustSec

Resource Endpoints netapi Description

Security Group Tags

5

SGT values for microsegmentation

SGACLs

5

Security Group ACL content

IP-SGT Mappings

5

Static IP to SGT assignments

Egress Matrix

5

SGT source/destination policies

ANC (Adaptive Network Control)

Resource Endpoints netapi Description

ANC Policies

5

Quarantine, shutdown policies

ANC Endpoints

5

Endpoint-to-policy assignments

Common Operations

List Resources

curl
curl -sk -u "${ISE_AUTH}" \
  "https://${ISE_HOST}:9060/ers/config/endpoint" \
  -H "Accept: application/json" | jq '.SearchResult.resources'
netapi
netapi ise get-endpoints

Get Single Resource

curl
# By ID
curl -sk -u "${ISE_AUTH}" \
  "https://${ISE_HOST}:9060/ers/config/endpoint/${ID}" \
  -H "Accept: application/json"

# By name
curl -sk -u "${ISE_AUTH}" \
  "https://${ISE_HOST}:9060/ers/config/endpoint/name/${NAME}" \
  -H "Accept: application/json"
netapi
netapi ise get-endpoint "C8:5B:76:C6:59:62"

Create Resource

curl
curl -sk -u "${ISE_AUTH}" \
  "https://${ISE_HOST}:9060/ers/config/endpoint" \
  -H "Content-Type: application/json" \
  -H "Accept: application/json" \
  -X POST \
  -d '{"ERSEndPoint": {"mac": "AA:BB:CC:DD:EE:FF", ...}}'
netapi
netapi ise create-endpoint "AA:BB:CC:DD:EE:FF" --group "Linux-Workstations"

Update Resource

curl
curl -sk -u "${ISE_AUTH}" \
  "https://${ISE_HOST}:9060/ers/config/endpoint/${ID}" \
  -H "Content-Type: application/json" \
  -H "Accept: application/json" \
  -X PUT \
  -d '{"ERSEndPoint": {"id": "${ID}", "mac": "AA:BB:CC:DD:EE:FF", ...}}'

Delete Resource

curl
curl -sk -u "${ISE_AUTH}" \
  "https://${ISE_HOST}:9060/ers/config/endpoint/${ID}" \
  -X DELETE
netapi
netapi ise delete-endpoint "AA:BB:CC:DD:EE:FF"

Filtering

ERS supports query string filters:

# ERS Filter Operators
EQ        - Equals
NEQ       - Not Equals
STARTSW   - Starts With
ENDSW     - Ends With
CONTAINS  - Contains
GT        - Greater Than
LT        - Less Than
GE        - Greater Than or Equal
LE        - Less Than or Equal

# Examples
filter=mac.STARTSW.C8:5B
filter=name.CONTAINS.workstation
filter=staticGroupAssignment.EQ.true
Example
# Find endpoints starting with specific MAC prefix
curl -sk -u "${ISE_AUTH}" \
  "https://${ISE_HOST}:9060/ers/config/endpoint?filter=mac.STARTSW.C8:5B" \
  -H "Accept: application/json"

Pagination

Pagination

ERS API Pagination

ERS supports page and size query parameters:

# First page, 100 results
curl -sk -u "${ISE_AUTH}" \
  "${BASE_URL}/endpoint?page=1&size=100" \
  -H "Accept: application/json"

# Page through all results
PAGE=1
SIZE=100
while true; do
  RESULT=$(curl -sk -u "${ISE_AUTH}" \
    "${BASE_URL}/endpoint?size=${SIZE}&page=${PAGE}" \
    -H "Accept: application/json")

  COUNT=$(echo "$RESULT" | jq '.SearchResult.resources | length')
  echo "$RESULT" | jq -r '.SearchResult.resources[].name'

  [[ "$COUNT" -lt "$SIZE" ]] && break
  ((PAGE++))
done
Parameter Description

page

Page number (1-based)

size

Results per page (max 100)

OpenAPI Pagination

OpenAPI uses similar pagination:

# List with pagination
curl -sk -u "${ISE_AUTH}" \
  "https://${ISE_HOST}/api/v1/policy/network-access/policy-set?page=1&size=20" \
  -H "Accept: application/json"

netapi Pagination

netapi handles pagination automatically for list operations:

# Returns all results (auto-paginated)
netapi ise get-endpoints

# For very large datasets, use API call with explicit pagination
netapi ise api-call ers GET '/ers/config/endpoint?page=1&size=100'

Response Schema

ERS Response Structure

All ERS API responses follow a consistent structure:

List Operations (GET collection)

{
  "SearchResult": {
    "total": 142,
    "resources": [
      {
        "id": "uuid-string",
        "name": "resource-name",
        "description": "optional description",
        "link": {
          "rel": "self",
          "href": "https://ise:9060/ers/config/resource/uuid",
          "type": "application/json"
        }
      }
    ]
  }
}

Single Resource (GET by ID/name)

{
  "ERSResourceName": {
    "id": "uuid-string",
    "name": "resource-name",
    "description": "optional description",
    // Resource-specific fields
    "link": {
      "rel": "self",
      "href": "https://ise:9060/ers/config/resource/uuid"
    }
  }
}

Create/Update Success (POST/PUT)

{
  "UpdatedFieldsList": {
    "updatedField": [
      {
        "field": "fieldName",
        "oldValue": "old",
        "newValue": "new"
      }
    ]
  }
}

Error Response

{
  "ERSResponse": {
    "operation": "POST-create",
    "messages": [
      {
        "title": "Error description",
        "type": "ERROR",
        "code": "Application error code"
      }
    ]
  }
}

jq Extraction Patterns

# List all resources
jq '.SearchResult.resources[]'

# Get names only
jq -r '.SearchResult.resources[].name'

# Get ID and name pairs
jq '.SearchResult.resources[] | {id, name}'

# Single resource fields
jq '.ERSEndPoint | {mac: .mac, group: .groupId}'

Error Handling

Error Handling

Check HTTP Status

# Capture both body and status code
response=$(curl -sk -w "\n%{http_code}" -u "${ISE_AUTH}" \
  "${BASE_URL}/endpoint/nonexistent" \
  -H "Accept: application/json")

http_code=$(echo "$response" | tail -1)
body=$(echo "$response" | sed '$d')

if [[ "$http_code" -ge 200 && "$http_code" -lt 300 ]]; then
  echo "Success: $body" | jq .
else
  echo "Error HTTP $http_code:" >&2
  echo "$body" | jq -r '.ERSResponse.messages[0].title // .message // .' >&2
  exit 1
fi

Parse ERS Errors

# Extract ERS error message
jq -r '.ERSResponse.messages[0].title // "Unknown error"'

# Full error details
jq '.ERSResponse.messages[]'

Parse OpenAPI Errors

# Extract OpenAPI error
jq -r '.response.message // .message // "Unknown error"'

Retry Logic

# Retry with exponential backoff
retry_request() {
  local max_attempts=3
  local delay=1

  for ((i=1; i<=max_attempts; i++)); do
    response=$(curl -sk -w "\n%{http_code}" "$@")
    http_code=$(echo "$response" | tail -1)

    if [[ "$http_code" -lt 500 ]]; then
      echo "$response" | sed '$d'
      return 0
    fi

    echo "Attempt $i failed (HTTP $http_code), retrying in ${delay}s..." >&2
    sleep "$delay"
    ((delay*=2))
  done

  echo "All attempts failed" >&2
  return 1
}

netapi Error Handling

# netapi returns non-zero on error
if ! result=$(netapi ise get-endpoint "XX:XX:XX:XX:XX:XX" 2>&1); then
  echo "Error: $result" >&2
  exit 1
fi

# Or use set -e for automatic exit on error
set -e
netapi ise get-endpoint "C8:5B:76:C6:59:62"

See Also