Routelearn.net
Course menu

Course 15: Automation and ProgrammabilityLesson 1.2 (2 of 4 in this course)89 of 91 in the CCNA series

REST APIs and JSON

HTTP verbs and CRUD, status codes, authentication, and reading and writing JSON data.

Intermediate · 12 min read

REST API (Representational State Transfer application programming interface) is an HTTP-based interface in which each resource has its own URI and clients act on it with standard verbs such as GET, POST, PUT and DELETE. Each request is stateless, and data is usually exchanged as JSON (JavaScript Object Notation) text.

In simple terms: A REST API lets a script talk to a network device or controller the way a browser talks to a website. The script asks for or sends data over HTTP, and the answer comes back as structured text a program can read.

A real-life situation

An auditor wants a list of every switch with its model, software version and serial number, by Friday. You could log in to each one and run show version, then copy the results into a spreadsheet. Or you could ask Catalyst Center, which already knows all of this, with one HTTPS request and get back clean, structured data a script can turn into a report in seconds.

That request is a REST API call, and the data comes back as JSON. Both are now basic tools for network engineers, and both are on the CCNA exam.

What a REST API is

An API (application programming interface) is a defined way for one program to ask another for data or actions. REST (representational state transfer) is a style of API built on HTTP, the same protocol web browsers use. A REST API has these properties:

  • Client-server: the client (your script) asks; the server (the controller or device) answers.
  • Stateless: each request stands alone and carries its own authentication. The server doesn't remember earlier requests.
  • Cacheable: responses can say whether they may be cached and reused.
  • Uniform interface: every thing you can work with is a resource with its own address, a URI, and you act on it with standard HTTP verbs.

A URI for the device list in Catalyst Center breaks down like this:

https://
scheme: HTTP inside TLS
cc1.example.com
host: the server
/dna/intent/api/v1/network-device
path: the resource
?hostname=SW1
query: filter the result
https://cc1.example.com/dna/intent/api/v1/network-device?hostname=SW1

HTTP verbs and CRUD

Everything you do with data is one of four actions, called CRUD: create, read, update, delete. REST maps each one to an HTTP verb (also called a method):

CRUD actionHTTP verbNetwork example
CreatePOSTAdd a new VLAN, or ask for an auth token
ReadGETList devices, read an interface's settings
UpdatePUT (replace all) or PATCH (change some fields)Change an interface description
DeleteDELETERemove a VLAN or a device from inventory

HTTP status codes

Every response starts with a three-digit status code. The first digit tells you the class: 2xx success, 4xx the client (you) made a mistake, 5xx the server failed.

CodeMeaningWhen you see it
200 OKSuccess, data in the bodyA GET that worked
201 CreatedA new resource was madeA POST that created something
202 AcceptedRequest taken, work still runningCatalyst Center tasks that take time; you check the task later
204 No ContentSuccess, nothing to returnA PATCH, PUT or DELETE that worked
400 Bad RequestThe request is malformedBroken JSON, a missing field
401 UnauthorizedNot authenticatedWrong password, missing or expired token
403 ForbiddenAuthenticated but not allowedA read-only account trying to change something
404 Not FoundNo such resourceA typo in the URI
500 Internal Server ErrorThe server failedA bug or crash on the server side

Authentication

  • Basic authentication: the client sends Authorization: Basic followed by username:password encoded in Base64. Base64 is an encoding, not encryption, so this is only acceptable inside HTTPS.
  • Token-based: you log in once (often with Basic authentication) and receive a token, a long random string. You send the token with every later request. Catalyst Center uses an X-Auth-Token header; tokens expire after a set time (one hour by default).
  • API keys: a fixed secret string issued to an application, sent in a header.
  • OAuth 2.0: a separate authorization server issues short-lived Bearer tokens. Common with cloud services.

Why it works that way

REST won because it reuses what already exists. HTTP and TLS run on every operating system, pass through firewalls on TCP 443, and have libraries in every programming language. Statelessness means a controller cluster can send each request to any node, since no node needs to remember your session. And JSON is easy for people to read and trivial for programs to parse, unlike the CLI output a script would otherwise have to scrape line by line.

How it works step by step

Here is the audit request from the course lab: the NetOps PC (10.10.0.50) talks to Catalyst Center (cc1.example.com, 10.10.0.10) on its northbound API.

Step 1 of 4 · POST /dna/system/api/v1/auth/token
NetOps PC
10.10.0.50
HTTPS
TCP 443, TLS encrypted
Catalyst Center
cc1.example.com

If the token has expired, the GET returns 401 Unauthorized and the script must request a new token.

The raw HTTP request for the device list looks like this:

Illustrative example · written for this lesson; check current vendor documentation for exact names
GET request (headers)HTTP
GET /dna/intent/api/v1/network-device?hostname=SW1 HTTP/1.1
Host: cc1.example.com
Accept: application/json
X-Auth-Token: eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9...
  • GET: the verb: read only, no body
  • Accept: asks for the response in JSON
  • X-Auth-Token: the token from the login request

Reading JSON

JSON (JavaScript Object Notation) is a text format for structured data. It has only a few rules:

  • An object is wrapped in curly braces { } and holds key/value pairs separated by commas.
  • A key is always a string in double quotes, followed by a colon: "hostname": "SW1".
  • An array is an ordered list in square brackets [ ].
  • A value is a string (in double quotes), a number, true or false, null, an object or an array.
  • No comments, no single quotes, no comma after the last item. Spaces and line breaks don't matter.

This is the body Catalyst Center returns for SW1:

Illustrative example · written for this lesson; check current vendor documentation for exact names
GET /dna/intent/api/v1/network-device?hostname=SW1 · response bodyJSON
{
  "response": [
    {
      "hostname": "SW1",
      "managementIpAddress": "10.10.1.11",
      "platformId": "C9300-24P",
      "softwareVersion": "17.9.4",
      "role": "ACCESS",
      "reachabilityStatus": "Reachable",
      "serialNumber": "FOC2211X0AB",
      "upTime": "21 days, 4:12:09.00"
    }
  ],
  "version": "1.0"
}
  • { … }: the outer object has two keys: response and version
  • "response": [ … ]: an array, here with one object per matching device (just SW1)
  • "hostname": "SW1": a key/value pair whose value is a string

To get the software version, a script follows the path response → first item → softwareVersion (in Python: data["response"][0]["softwareVersion"]). A short illustrative Python script that makes the whole audit request:

Illustrative example · written for this lesson; check current vendor documentation for exact names
audit.pyPython
import requests

BASE = "https://cc1.example.com"

# 1. Log in once with Basic auth and keep the token
token = requests.post(f"{BASE}/dna/system/api/v1/auth/token",
                      auth=("netops", "Str0ng-Secret")).json()["Token"]

# 2. Read the device list, sending the token in a header
devices = requests.get(f"{BASE}/dna/intent/api/v1/network-device",
                       headers={"X-Auth-Token": token}).json()["response"]

for d in devices:
    print(d["hostname"], d["platformId"], d["softwareVersion"], d["serialNumber"])

JSON is one of three data formats you should recognize:

FormatLooks likeWhere you meet it
JSON{"vlan": 10}REST APIs, RESTCONF, most controllers
XML<vlan>10</vlan>NETCONF, older APIs
YAMLvlan: 10 (indentation, no braces)Ansible playbooks, config files

How to configure RESTCONF on Cisco IOS XE

Controllers have their REST API on from the start. Cisco IOS XE devices can offer one too: RESTCONF, a standard (RFC 8040) REST API that reads and changes the device configuration using YANG data models. Here is R1 in the course lab.

username netadmin privilege 15 secret Str0ng-Secret aaa new-model aaa authentication login default local aaa authorization exec default local

RESTCONF needs a privilege 15 user and AAA with local authentication and exec authorization.

ip http secure-server ip http authentication local

Starts the HTTPS server (TCP 443) and checks logins against the local user database.

restconf

Global config: turns on the RESTCONF API at https://<device>/restconf/.

The full configuration on R1:

hostname R1 username netadmin privilege 15 secret Str0ng-Secret ! aaa new-model aaa authentication login default local aaa authorization exec default local ! interface GigabitEthernet0/0/0 description Management segment ip address 10.10.0.1 255.255.255.0 no shutdown ! ip http secure-server ip http authentication local no ip http server ! restconf

no ip http server disables plain HTTP so credentials are never sent unencrypted.

How to verify it

Test with curl, a command-line HTTP client, from the NetOps PC. RESTCONF uses its own media type, application/yang-data+json. The / characters in an interface name must be URL-encoded as %2F.

Example output · curl on the NetOps PC (Linux), written for this lesson from Cisco RESTCONF documentation
netops$ curl -k -i -u netadmin:Str0ng-Secret -H "Accept: application/yang-data+json" https://r1.example.com/restconf/data/ietf-interfaces:interfaces/interface=GigabitEthernet0%2F0%2F0
HTTP/1.1 200 OK
Content-Type: application/yang-data+json

{
  "ietf-interfaces:interface": {
    "name": "GigabitEthernet0/0/0",
    "description": "Management segment",
    "type": "iana-if-type:ethernetCsmacd",
    "enabled": true,
    "ietf-ip:ipv4": {
      "address": [
        {
          "ip": "10.10.0.1",
          "netmask": "255.255.255.0"
        }
      ]
    },
    "ietf-ip:ipv6": {
    }
  }
}
200 OK and a JSON body: RESTCONF is working. The keys come from the ietf-interfaces YANG model, so they look the same on any vendor that supports that model. (-k skips certificate checking because the lab router uses a self-signed certificate; don't do that in production.)

Now change the description with PATCH, which updates only the fields sent:

Example output · curl on the NetOps PC (Linux), written for this lesson from Cisco RESTCONF documentation
netops$ curl -k -i -u netadmin:Str0ng-Secret -X PATCH -H "Content-Type: application/yang-data+json" -d '{"ietf-interfaces:interface": {"name": "GigabitEthernet0/0/0", "description": "To MGMT-SW"}}' https://r1.example.com/restconf/data/ietf-interfaces:interfaces/interface=GigabitEthernet0%2F0%2F0
HTTP/1.1 204 No Content
204 No Content: the change worked and there is nothing to send back.
Example output · based on Cisco documentation; exact format varies by platform and software version
R1#show running-config interface GigabitEthernet0/0/0
Building configuration...

Current configuration : 112 bytes
!
interface GigabitEthernet0/0/0
 description To MGMT-SW
 ip address 10.10.0.1 255.255.255.0
 negotiation auto
end
The CLI shows the new description. RESTCONF and the CLI change the same running configuration.

What goes wrong and how to troubleshoot it

ResultLikely causeFix
Connection refusedip http secure-server or restconf missing, or TCP 443 blockedCheck show running-config | include http|restconf and any ACL
401 UnauthorizedWrong credentials, user not privilege 15, AAA not set, or an expired tokenCheck the user and AAA lines; request a new token
404 Not FoundTypo in the path, or / in the interface name not encodedUse %2F; check the YANG model name
400 Bad RequestBroken JSON: single quotes, trailing comma, missing braceRun the body through a JSON validator
415 Unsupported Media TypeWrong Content-Type headerUse application/yang-data+json for RESTCONF

Common mistakes

  • Confusing 401 (who are you?) with 403 (I know who you are, but no).
  • Using PUT when you meant PATCH, and wiping fields you didn't send.
  • Thinking Base64 hides the password. It doesn't; HTTPS does.
  • Writing JSON with single quotes or a comma after the last item.
  • Forgetting the token on the second request: REST servers don't remember you.

💡 Exam tip: the CCNA asks you to describe REST APIs (authentication types, CRUD, HTTP verbs and data encoding) and to recognize the components of JSON. Expect to match CRUD actions to verbs, pick the meaning of a status code, count the objects or arrays in a JSON sample, or spot why a JSON snippet is invalid. Remember: objects use { }, arrays use [ ], keys are always double-quoted strings.

Key takeaways

  • REST APIs use HTTP(S): client-server, stateless, resources identified by URIs.
  • CRUD: POST creates, GET reads, PUT/PATCH update, DELETE deletes.
  • 2xx success, 4xx client error (401 not authenticated, 403 not allowed, 404 not found), 5xx server error.
  • Basic auth is Base64, not encryption; tokens are sent on every request.
  • JSON: objects in braces, arrays in brackets, double-quoted keys, no comments.
  • On IOS XE: ip http secure-server plus restconf turns on a REST API.

Check yourself

Predict · scenario 1

A script needs to add a new VLAN through a controller's REST API. Which HTTP verb fits best?

Predict · scenario 2

A GET to Catalyst Center worked an hour ago. Now the same request returns 401. What is the most likely cause?

Predict · scenario 3

Which of these is valid JSON?

Predict · scenario 4

In {"response": [{"hostname": "SW1"}, {"hostname": "SW2"}]}, what is the value of response?

Predict · scenario 5

A PATCH to R1's RESTCONF API returns 204 No Content. What happened?

FAQ

What is the difference between PUT and PATCH?
PUT replaces the whole resource with what you send, so any field you leave out is removed or reset. PATCH changes only the fields you send and leaves the rest alone. For a single interface description, PATCH is the safer choice.
Is Basic authentication secure?
Only inside HTTPS. Basic authentication sends username:password encoded in Base64, which anyone can decode. TLS encrypts the whole request, which is why REST APIs on network devices and controllers run over HTTPS. Token-based authentication is still preferred, because the password is sent once and the token expires.
What does it mean that REST is stateless?
The server keeps no memory of earlier requests. Every request must carry everything needed to process it, including the authentication token. That makes REST servers simple to scale, but it is why you must add the token header to every call.
Does JSON allow comments?
No. Standard JSON has no comment syntax, and a trailing comma after the last item is also an error. Keys must be strings in double quotes. YAML, which is used by Ansible, does allow comments with #.