18.3 REST API Architecture, HTTP Verbs, Security & Cisco Controller APIs

Key Takeaways

  • REST (Representational State Transfer) is an architectural style governed by six constraints: Client-Server separation, Statelessness, Cacheability, Layered System, Uniform Interface, and optional Code-on-Demand.
  • HTTP verbs define CRUD operations where GET (safe and idempotent) retrieves data, POST (unsafe and non-idempotent) creates resources or triggers actions, PUT (idempotent) replaces or creates entire resources, PATCH modifies partial resources, and DELETE (idempotent) removes resources.
  • HTTP response status codes provide deterministic operational signaling: 2xx indicates success (200 OK, 201 Created, 202 Accepted, 204 No Content), 4xx indicates client error (400 Bad Request, 401 Unauthorized, 403 Forbidden, 404 Not Found), and 5xx indicates server failure.
  • The two Cisco controllers authenticate differently: Catalyst Center uses token-based auth via POST /dna/system/api/v1/auth/token with HTTP Basic Auth, returning a JWT passed in the x-auth-token header and polling long-running work at /dna/intent/api/v1/task/{taskId}, while Catalyst SD-WAN Manager (vManage) uses cookie-based session auth via POST /j_security_check followed by a mandatory CSRF token from GET /dataservice/client/token sent in the X-XSRF-TOKEN header on every state-changing call.
  • REST API security rests on four separable controls: TLS for transport, an authentication credential such as a bearer token, RBAC authorization enforced server-side, and rate limiting; a 401 means the credential failed while a 403 means the credential was accepted but the role is insufficient.
Last updated: August 2026

18.3 REST API Architecture, HTTP Verbs, Cisco Catalyst Center & SD-WAN vManage APIs

Core Blueprint Focus: Cisco 350-401 ENCOR v1.2 topics 6.4 (describe APIs for Cisco Catalyst Center and SD-WAN Manager), 6.5 (interpret REST API response codes and results in payload) and 5.3 (describe REST API security) require comprehensive mastery of RESTful Application Programming Interfaces (APIs). Network engineers must understand the six REST architectural constraints, HTTP verb semantics and idempotency, HTTP response status codes (2xx, 4xx, 5xx), and hands-on integration workflows for Cisco's premier enterprise controllers: Cisco Catalyst Center (DNA Center) and Cisco SD-WAN vManage.

REST (Representational State Transfer) APIs provide a lightweight, human-readable, and web-standardized mechanism for network management systems to programmatically interact with SDN controllers, orchestrators, and network devices.

+---------------------------------------------------------------------------------------------------+
|                             REST API CLIENT-SERVER ARCHITECTURE                                  |
+---------------------------------------------------------------------------------------------------+
|                                                                                                   |
|  +-----------------------+                                            +------------------------+  |
|  |   API CLIENT / SCRIPT |                                            |   ENTERPRISE CONTROLLER|  |
|  |   - Python Requests   |                                            |   - Catalyst Center    |  |
|  |   - Postman / cURL    |                                            |   - SD-WAN vManage     |  |
|  +-----------------------+                                            +------------------------+  |
|              |                                                                     |              |
|              |  1. HTTP Request (Method: GET/POST/PUT/PATCH/DELETE)                |              |
|              |     URI: https://controller.local/dna/intent/api/v1/network-device   |              |
|              |     Headers: { "x-auth-token": "...", "Accept": "application/json" }|              |
|              |     Payload (JSON Body): { "hostname": "core-sw01" }                |              |
|              |-------------------------------------------------------------------->|              |
|              |                                                                     |              |
|              |  2. HTTP Response                                                   |              |
|              |     Status Code: 200 OK / 201 Created / 202 Accepted                |              |
|              |     Headers: { "Content-Type": "application/json" }                 |              |
|              |     Payload (JSON Body): { "response": { "status": "Success" } }    |              |
|              |<--------------------------------------------------------------------|              |
+---------------------------------------------------------------------------------------------------+

1. REST Architectural Constraints

Defined by Roy Fielding in 2000, an API is strictly considered RESTful only if it adheres to six architectural constraints:

  1. Client-Server Architecture: Strict separation of concerns. The client handles user interface and application state; the server handles data storage, business logic, and security. Both evolve independently.
  2. Statelessness: Every HTTP request from client to server must contain all the context and credentials necessary to understand and process the request. The server stores no client session context between requests.
  3. Cacheability: Responses must explicitly define themselves as cacheable or non-cacheable (via HTTP Cache-Control headers) to prevent clients from reusing stale data while improving performance.
  4. Layered System: The client cannot tell whether it is connected directly to the end server or to an intermediary (e.g., load balancer, reverse proxy, API gateway, TLS decryptor, or security firewall).
  5. Uniform Interface: Standardized interaction through four sub-constraints:
    • Identification of Resources: Unique URIs (e.g., /api/v1/devices/101).
    • Manipulation through Representations: Clients modify resources using representations (e.g., JSON or XML payloads).
    • Self-Descriptive Messages: Headers (Content-Type, Accept) describe payload parsing.
    • HATEOAS (Hypermedia As The Engine Of Application State): Responses include hyperlinks to related actions.
  6. Code on Demand (Optional): Servers can temporarily extend client functionality by transferring executable code (e.g., JavaScript applets).

2. HTTP Verbs, CRUD Operations & Idempotency

REST maps HTTP verbs to database CRUD (Create, Read, Update, Delete) operations. Understanding Safety and Idempotency is a crucial ENCOR exam concept.

  • Safe Methods: HTTP methods that do not alter server state (read-only operations like GET and HEAD).
  • Idempotent Methods: An HTTP method is idempotent if executing it once produces the exact same server resource state as executing it multiple times consecutively ($f(f(x)) = f(x)$).
+---------------------------------------------------------------------------------------------------+
|                         HTTP VERBS, CRUD, AND IDEMPOTENCY MATRIX                                  |
+---------------------------------------------------------------------------------------------------+
|  HTTP Verb  | CRUD Mapping  | Safe? | Idempotent? | Description & Functional Behavior             |
| :---------- | :------------ | :---- | :---------- | :-------------------------------------------- |
| **GET**     | **Read**      | Yes   | **Yes**     | Retrieves resource representation. No side-   |
|             |               |       |             | effects on the server state.                   |
| **POST**    | **Create** /  | No    | **No**      | Creates a subordinate resource or executes     |
|             | **Action**    |       |             | an RPC action. Multiple POSTs create copies.  |
| **PUT**     | **Replace**   | No    | **Yes**     | Completely replaces target resource or creates |
|             |               |       |             | it if non-existent. Repeated calls yield same.|
| **PATCH**   | **Update**    | No    | **No***     | Modifies specific fields of an existing        |
|             | (Partial)     |       |             | resource without touching remaining fields.   |
| **DELETE**  | **Delete**    | No    | **Yes**     | Removes the target resource. Deleting an       |
|             |               |       |             | already-deleted resource yields same state.    |
+---------------------------------------------------------------------------------------------------+
* Note: PATCH is technically non-idempotent by specification (RFC 5789), although specific implementations may behave idempotently.

3. HTTP Response Status Codes

HTTP status codes are 3-digit integers categorized into five classes:

+---------------------------------------------------------------------------------------------------+
|                             HTTP STATUS CODE CLASSIFICATION                                       |
+---------------------------------------------------------------------------------------------------+
|  Code Range | Class Name          | Description & Prominent Examples                             |
| :---------- | :------------------ | :------------------------------------------------------------ |
| **1xx**     | **Informational**   | Request received, continuing process (e.g., 100 Continue).    |
| **2xx**     | **Success**         | Action received, understood, and accepted.                    |
|             |                     | - **200 OK**: Request succeeded; payload returned.           |
|             |                     | - **201 Created**: Resource created successfully.             |
|             |                     | - **202 Accepted**: Request accepted for async task processing|
|             |                     | - **204 No Content**: Request succeeded; no body returned.    |
| **3xx**     | **Redirection**     | Further action needed to complete request (301, 304).         |
| **4xx**     | **Client Error**    | Request contains bad syntax or cannot be fulfilled.           |
|             |                     | - **400 Bad Request**: Malformed JSON or invalid syntax.      |
|             |                     | - **401 Unauthorized**: Missing or invalid authentication.   |
|             |                     | - **403 Forbidden**: Authenticated, but lacking permissions.  |
|             |                     | - **404 Not Found**: Target URI resource does not exist.      |
|             |                     | - **405 Method Not Allowed**: HTTP verb unsupported on URI.   |
|             |                     | - **409 Conflict**: Resource state conflict (e.g., duplicate).|
| **5xx**     | **Server Error**    | Server failed to fulfill an apparently valid request.         |
|             |                     | - **500 Internal Server Error**: Generic unhandled exception. |
|             |                     | - **502 Bad Gateway**: Upstream proxy/service failure.        |
|             |                     | - **503 Service Unavailable**: Controller overloaded/rebooting|
|             |                     | - **504 Gateway Timeout**: Upstream gateway timed out.        |
+---------------------------------------------------------------------------------------------------+
Loading diagram...
Catalyst Center Token Authentication and Asynchronous Task Polling

4. Cisco Catalyst Center REST API Integration

Cisco Catalyst Center provides Intent-Based Networking APIs. Communication is structured around two distinct operational phases: Authentication Token Acquisition and Asynchronous Task Polling.

Authentication Workflow

  1. Endpoint: POST https://<dnac-ip>/dna/system/api/v1/auth/token
  2. Authentication Header: Authorization: Basic <base64-encoded user:password>
  3. Response: Returns a JSON payload containing {"Token": "<JWT_STRING>"} (valid for 1 hour).
  4. Subsequent Calls: Pass the token in the custom header x-auth-token: <JWT_STRING>.

Asynchronous Task Polling Mechanism

When creating, updating, or deleting complex infrastructure (such as provisioning an access switch or deploying an SSID), Catalyst Center returns HTTP 202 Accepted containing a taskId.

  • Long-running network operations cannot block the HTTP connection.
  • The automation script must poll GET https://<dnac-ip>/dna/intent/api/v1/task/{taskId} until response.isError == False and response.progress == "Completed".
import requests
import time
import urllib3
urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)

DNAC_IP = "10.10.10.100"
BASE_URL = f"https://{DNAC_IP}"

# 1. Acquire Authentication Token
auth_url = f"{BASE_URL}/dna/system/api/v1/auth/token"
auth_resp = requests.post(auth_url, auth=("admin", "Cisco123!"), verify=False)
token = auth_resp.json()["Token"]

headers = {
    "x-auth-token": token,
    "Content-Type": "application/json",
    "Accept": "application/json"
}

# 2. Trigger Async Intent Action (HTTP 202 Accepted)
payload = {"siteId": "site-101", "deviceIp": ["10.1.10.50"]}
provision_resp = requests.post(f"{BASE_URL}/dna/intent/api/v1/business/sda/hostonboarding/user-device", 
                               headers=headers, json=payload, verify=False)

if provision_resp.status_code == 202:
    task_id = provision_resp.json()["response"]["taskId"]
    print(f"Task initiated: {task_id}. Polling execution status...")
    
    # 3. Poll Task Status
    task_url = f"{BASE_URL}/dna/intent/api/v1/task/{task_id}"
    while True:
        task_data = requests.get(task_url, headers=headers, verify=False).json()["response"]
        if task_data.get("endTime"):
            if task_data.get("isError"):
                print(f"Task failed: {task_data.get('failureReason')}")
            else:
                print("Task completed successfully!")
            break
        print(f"Current Progress: {task_data.get('progress', 'Executing')}...")
        time.sleep(2)
Loading diagram...
Cisco SD-WAN vManage Cookie and CSRF Token Authentication Workflow

5. Cisco SD-WAN (vManage) REST API Integration

Cisco SD-WAN vManage employs a dual-mechanism security model: Session Cookies for authentication and CSRF Tokens for Cross-Site Request Forgery prevention.

The Two-Step vManage Authentication Sequence

  1. Step 1: Session Authentication (POST /j_security_check):
    • Request is sent with form URL-encoded data containing j_username and j_password.
    • vManage authenticates the credentials and returns a JSESSIONID session cookie.
  2. Step 2: CSRF Token Acquisition (GET /dataservice/client/token):
    • In vManage versions 19.2+, all state-modifying requests (POST, PUT, DELETE) require a valid Cross-Site Request Forgery (CSRF) token.
    • The client sends a GET request to /dataservice/client/token including the JSESSIONID cookie.
    • vManage returns a raw text CSRF token string.
  3. Step 3: Subsequent API Calls:
    • For GET requests: Supply the JSESSIONID cookie.
    • For POST / PUT / DELETE requests: Supply both the JSESSIONID cookie and the header X-XSRF-TOKEN: <token_string>.
import requests
import urllib3
urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)

VMANAGE_IP = "192.168.100.1"
PORT = 8443
BASE_URL = f"https://{VMANAGE_IP}:{PORT}"

session = requests.Session()
session.verify = False

# 1. Authenticate and retrieve JSESSIONID cookie
login_url = f"{BASE_URL}/j_security_check"
login_payload = {"j_username": "admin", "j_password": "vManagePassword123!"}
login_resp = session.post(login_url, data=login_payload)

# 2. Retrieve Cross-Site Request Forgery (CSRF / XSRF) Token
token_url = f"{BASE_URL}/dataservice/client/token"
token_resp = session.get(token_url)
csrf_token = token_resp.text

# 3. Update session headers with the CSRF token for future state-modifying requests
session.headers.update({"X-XSRF-TOKEN": csrf_token, "Content-Type": "application/json"})

# 4. Query Edge Routers from vManage Inventory
devices_resp = session.get(f"{BASE_URL}/dataservice/device")
devices = devices_resp.json()["data"]
for dev in devices:
    print(f"Hostname: {dev.get('host-name')} | System IP: {dev.get('system-ip')} | Reachability: {dev.get('reachability')}")

Architectural Comparison: Catalyst Center vs. vManage APIs

FeatureCisco Catalyst CenterCisco SD-WAN vManage
Authentication EndpointPOST /dna/system/api/v1/auth/tokenPOST /j_security_check
Auth MechanismJWT Token (x-auth-token header)JSESSIONID Session Cookie
CSRF DefenseIntegrated into JWT Bearer TokenDedicated X-XSRF-TOKEN Header
CSRF EndpointN/AGET /dataservice/client/token
Default PortTCP 443TCP 8443 (or 443)
Execution PatternAsync Task Polling (/v1/task/{taskId})Async Action Polling (/device/action/status)

6. REST API Security (ENCOR v1.2 Topic 5.3)

Topic 5.3 sits in the Security domain, not the Automation domain, and its verb is describe. The exam wants you to reason about which control failed, not to write an authorization server. Four controls are separable and every one of them can fail independently.

6.1 Transport Security

Every Cisco controller API is HTTPS only. TLS provides confidentiality, integrity, and server authentication for the API session — but only if the client actually validates the certificate.

This is the security caveat behind the verify=False shortcut shown earlier in Section 18.1. Disabling certificate verification is acceptable in a lab with a self-signed controller certificate; in production it removes the only defence against an on-path attacker impersonating the controller, and your script will happily hand its administrative credentials to whatever answers on port 443. The production fix is to install the controller's certificate into the client trust store (or pass verify='/path/to/ca-bundle.pem'), never to leave verification off.

6.2 The Authentication Ladder

SchemeHow it worksWeakness
HTTP BasicAuthorization: Basic <base64(user:pass)>Base64 is encoding, not encryption — trivially reversible. Safe only inside TLS, and it sends the password on every call
API keyA long static string in a header or query parameterNever expires unless rotated; leaks permanently if logged
Bearer / session tokenShort-lived credential exchanged for the password onceMust be protected like a password for its lifetime
OAuth 2.0Authorization server issues scoped, expiring access tokens; refresh tokens renew themComplexity; token storage still matters
Mutual TLS (mTLS)Client also presents an X.509 certificateCertificate lifecycle management

The pattern both Cisco controllers use is bearer-token: authenticate once with Basic over TLS, then present a short-lived token on every subsequent call. That limits the exposure window of the real password to a single request.

  • Cisco Catalyst CenterPOST /dna/system/api/v1/auth/token with HTTP Basic returns a JSON body containing Token. That value goes into the X-Auth-Token header on every later call. The token lifetime is 60 minutes; after that the API returns 401 Unauthorized and the client must re-authenticate. A long-running script must therefore refresh proactively rather than assume the token survives the job.
  • Cisco Catalyst SD-WAN ManagerPOST /j_security_check returns a JSESSIONID cookie, then GET /dataservice/client/token returns an X-XSRF-TOKEN required on every state-changing verb.

6.3 Why SD-WAN Manager Needs a Second Token: CSRF

A JSESSIONID cookie is sent automatically by the browser on every request to that origin, including requests triggered by a malicious third-party page. That is Cross-Site Request Forgery: the attacker cannot read the response, but the victim's authenticated session performs the write anyway.

The defence is a token the attacker cannot read or guess and that is not sent automatically — hence a custom X-XSRF-TOKEN header. Same-origin policy prevents a foreign page from fetching it. This is why SD-WAN Manager enforces the second token only on POST, PUT, and DELETE: safe, read-only GET requests do not change state and do not need the protection. Catalyst Center does not need an equivalent because its token lives in a custom header rather than a cookie, and custom headers are never sent automatically.

6.4 Authorization Is Not Authentication

Once identity is established, RBAC decides what that identity may do. The HTTP status codes distinguish the two failures precisely, and the exam tests the distinction:

CodeMeaningRoot cause
401 UnauthorizedThe credential is missing, malformed, or expiredBad password, or an expired X-Auth-Token
403 ForbiddenThe credential was accepted but the role lacks permissionAn observer-role account attempting a write
429 Too Many RequestsRate limit exceededToo many calls per minute; back off and retry

Authorization must be enforced server-side. A client that merely hides a button has enforced nothing, because the API endpoint is still reachable with curl.

6.5 Rate Limiting and Denial of Service

Controllers throttle API clients to protect themselves. Catalyst Center returns HTTP 429 when a client exceeds its permitted call rate. The correct client behaviour is exponential backoff with jitter, honouring a Retry-After header when present. A script that retries immediately in a tight loop converts a throttle into a self-inflicted outage — the same failure shape as the ACL-logging punt storm in Section 16.2.

6.6 Secret Handling and Practical Hardening

  • Never put credentials or tokens in a URL query string. URLs are written to web-server access logs, proxy logs, and browser history; headers generally are not.
  • Never commit credentials to source control. Read them from environment variables or a secrets manager at run time.
  • Use a dedicated service account with least privilege, not a human administrator's account, so the API client cannot exceed its purpose and can be revoked independently.
  • Validate and constrain input the script sends; treat controller responses as untrusted data.
  • Log the request metadata, never the Authorization or X-Auth-Token header value.
import os, requests

BASE  = os.environ["CATC_BASE_URL"]            # secrets from the environment
CAFILE = os.environ["CATC_CA_BUNDLE"]          # real certificate validation

resp = requests.post(
    f"{BASE}/dna/system/api/v1/auth/token",
    auth=(os.environ["CATC_USER"], os.environ["CATC_PASS"]),
    verify=CAFILE,                             # NOT verify=False in production
    timeout=10,
)
resp.raise_for_status()
token = resp.json()["Token"]                   # valid for 60 minutes

devices = requests.get(
    f"{BASE}/dna/intent/api/v1/network-device",
    headers={"X-Auth-Token": token},           # token in a header, never the URL
    verify=CAFILE,
    timeout=30,
)
if devices.status_code == 401:
    ...   # token expired after 60 minutes -> re-authenticate
elif devices.status_code == 403:
    ...   # authenticated, but this service account's role cannot read inventory
elif devices.status_code == 429:
    ...   # rate limited -> exponential backoff with jitter
Test Your Knowledge

A network automation engineer is creating a Python script to deploy updated device templates across eighty Cisco Catalyst 8300 SD-WAN edge routers using the vManage REST API. The script successfully authenticates against /j_security_check and obtains a JSESSIONID cookie, but all subsequent POST requests to attach the device templates fail with an HTTP 403 Forbidden error. What missing implementation step causes this failure?

A
B
C
D
Test Your Knowledge

An automation engineer submits an HTTP POST request to Cisco Catalyst Center to provision an SDA fabric border node. The controller responds immediately with an HTTP 202 Accepted status code and a JSON payload containing a taskId and URL. What architectural pattern does this represent, and what action should the script take next?

A
B
C
D
Test Your Knowledge

A developer is designing an automation script to update the descriptions on several switch interfaces via REST. The developer wants to ensure that if a network glitch causes the script to retransmit an update request three times, the final state on the switch remains identical to a single execution without creating duplicate side effects. Which HTTP verb and operational characteristic satisfy this requirement?

A
B
C
D
Test Your Knowledge

An engineer executes a REST API call to retrieve the operational status of an interface on a Cisco Catalyst switch. The controller responds with an HTTP status code indicating that the client's request was formatted properly, but the requesting user account lacks sufficient Role-Based Access Control (RBAC) privileges to view the requested resource. Which HTTP status code was returned?

A
B
C
D
Test Your Knowledge

A long-running Python job authenticates to Cisco Catalyst Center, receives a token, and successfully retrieves inventory for 75 minutes. It then begins receiving HTTP 401 responses on every call, although the same service account still works correctly from a freshly started script. What is the cause?

A
B
C
D