Apcera REST API

The Apcera API is a collection of HTTP endpoints that accept and return Apcera resources. To call the API your application makes an HTTP request and parses the response. The request and response bodies are JSON objects that are represented by API model objects. This guide describes the operations available with the Apcera API and provides example requests and responses. For steps to perform common tasks with the API, see Apcera REST API Recipes.

API Hosts and Versions

Most Apcera REST API endpoints are invoked on a cluster's "api" host (GET api.try.apcera.net/v1/jobs, for example). However, APIs related to authentication and policy are invoked on a cluster's "auth" host (GET auth.bagel.buffalo.im/v1/policy, for example).

The Apcera API is version controlled and the current version is v1. The API version number is independent of the Apcera release number. The API version number must appear in the URL of every call (for example, GET /v1/packages HTTP/1.1).

Call Authentication

The Apcera API uses token-based authentication. Each API call must include the bearer token in the header of the HTTP request (Authorization: Bearer eyJ0eXAiO..., for example). To obtain an API token your application will typically use the Apcera authentication APIs. See Authenticating with the API Server for details.

For testing purposes, a quick way to obtain an API token is to copy it from your APC client's configuration ($HOME/.apc) file after logging in successfully.

To get the API token from your .apc file:

  1. Target your cluster using the APC command apc target <cluster-domain>.
  2. Enter the APC command apc login to begin the authentication process.
  3. Follow the steps in the APC output to authenticate using Google Auth.
  4. Once your client is authenticated, open the .apc file in your home directory ($HOME/.apc) with a text editor. After the cluster name you will see the "Bearer …" token string. For example:

     {
       "target": "http://example.com",
       "tokens": {
         "http://example.com": "Bearer eyJ0eXAiOiIiLCJhbGciOiIifQ....",
         "..."
       }
     }
    
  5. Copy the entire "Bearer " string from the ~/.apc file and submit it in the HTTP header with each API request, for example:

     GET /v1/apc/version HTTP/1.1
     Host: api.example.com
     Authorization: Bearer eyJ0eXAiOiIiLCJhbGciOiIifQ....
     Content-Type: application/json
    

Testing the API

You can test the Apcera API using cURL. cURL is a command line HTTP client that you can use to invoke a REST API such as Apcera’s without writing code. cURL is available for many operating systems and can be downloaded here: http://curl.haxx.se/download.html.

To invoke the Apcera API using cURL, use the following syntax:

curl -H "Authorization: Bearer <token>" <request URL>

For example, the following demonstrates a call to the GET /v1/jobs API using cURL:

curl -X GET -H "Content-Type: application/json" 
  -H "Authorization: Bearer <token>" "http://api.example.apcera-platform.io/v1/jobs"

Note that the default HTTP method used by cURL is GET. You can see the other cURL usage examples here.

As an alternative to cURL, you can test the Apcera API using Postman, a Google Chrome application that provides a user interface for testing REST APIs. You create a custom header containing the auth token (you can save as it as a preset) and provide the request URL and method type. Download Postman from here: https://www.getpostman.com/.

Using APC's trace mode

Each APC command you run (apc app create, for example) results in a one or more Apcera API requests. If you include the --trace flag in any APC command, the contents of each API request and response is saved to a log file named apc.log in the local directory from where you invoked APC. Looking at the contents of this file can be instructional to see the sequence of API calls that a given APC command requires.

For example, run the following command against your cluster:

$ apc app list --trace
** Trace mode on. Logs will appear in apc.log **
Working in "/sandbox/admin"
╭──────┬────────────────┬────────┬───────────┬────────────────────────────────────────────────╮
│ Name │ Namespace      │ Status │ Instances │ Routes                                         │
├──────┼────────────────┼────────┼───────────┼────────────────────────────────────────────────┤
│ web1 │ /sandbox/admin │ ready  │           │ http://web1-3ps9to.tutorial.apcera-platform.io │
│ web2 │ /sandbox/admin │ ready  │           │ http://web2-pd03a0.tutorial.apcera-platform.io │
╰──────┴────────────────┴────────┴───────────┴────────────────────────────────────────────────╯

Open apc.log to view its contents. You should see the HTTP request to GET /v1/jobs and JSON response containing the list of jobs.

$ cat apc.log
I0322 16:53:09.494776 90281 request.go:160 ctx="apc" trace="1"] -- Sending HTTP Request:
I0322 16:53:09.494792 90281 client_auth.go:357 ctx="apc" trace="1"] GET /v1/jobs?fqn=job%3A%3A%2Fsandbox%2Fadmin&health=true&matchPartialFQN=true&summary=true&tag=app HTTP/1.1
I0322 16:53:09.494799 90281 client_auth.go:357 ctx="apc" trace="1"] Host: api.tutorial.apcera-platform.io
I0322 16:53:09.494800 90281 client_auth.go:357 ctx="apc" trace="1"] User-Agent: APC/v2.0.0 (Continuum Client)
I0322 16:53:09.494802 90281 client_auth.go:357 ctx="apc" trace="1"] Authorization: Bearer eyJ0eXAiOiIiLCJhbGciOiIifQ.eyJpc3MiOiJhdXRoX3NlcnZlckBhcGNlcmEubWUiLCJhdWQiOiJhcGNlcmEubWUiLCJpYXQiOjE0NTg2NzgzNjcsImV4cCI6MTQ1ODc2NDc3NywicHJuIjoiYWRtaW5AYXBjZXJhLm1lIiwiY2xhaW1zIjpbeyJJc3N1ZXIiOiJhdXRoX3NlcnZlckBhcGNlcmEubWUiLCJUeXBlIjoiYXV0aFR5cGUiLCJWYWx1ZSI6ImJhc2ljQXV0aCJ9XX0.MEUCIELB4uTe6Rdze8st1blxWtVzyVZjUq6-C3NLGf9LlZt0AiEAuMsDr8uKuPDbX-Lh9OS1V2iFGKJNfTjlFy4pizgGBFQ
I0322 16:53:09.494805 90281 client_auth.go:357 ctx="apc" trace="1"] Hostname: Tims-MacBook-Pro.local-Client-Hostname
I0322 16:53:09.494807 90281 client_auth.go:357 ctx="apc" trace="1"] Accept-Encoding: gzip
I0322 16:53:09.494809 90281 client_auth.go:357 ctx="apc" trace="1"]
I0322 16:53:09.494810 90281 client_auth.go:357 ctx="apc" trace="1"]
I0322 16:53:09.889994 90281 request.go:184 ctx="apc" trace="2"] -- Received HTTP Response:
I0322 16:53:09.890006 90281 client_auth.go:357 ctx="apc" trace="2"] HTTP/1.1 200 OK
I0322 16:53:09.890017 90281 client_auth.go:357 ctx="apc" trace="2"] Transfer-Encoding: chunked
I0322 16:53:09.890018 90281 client_auth.go:357 ctx="apc" trace="2"] Connection: keep-alive
I0322 16:53:09.890020 90281 client_auth.go:357 ctx="apc" trace="2"] Content-Type: application/json
I0322 16:53:09.890021 90281 client_auth.go:357 ctx="apc" trace="2"] Date: Tue, 22 Mar 2016 23:53:09 GMT
I0322 16:53:09.890022 90281 client_auth.go:357 ctx="apc" trace="2"] Minimum-Apc-Version: 2.0.0
I0322 16:53:09.890024 90281 client_auth.go:357 ctx="apc" trace="2"] Server: nginx
I0322 16:53:09.890025 90281 client_auth.go:357 ctx="apc" trace="2"] Vary: Accept-Encoding
I0322 16:53:09.890028 90281 client_auth.go:357 ctx="apc" trace="2"]
I0322 16:53:09.890030 90281 client_auth.go:357 ctx="apc" trace="2"]
I0322 16:53:09.892560 90281 client_auth.go:357 ctx="apc" trace="2"] [{"uuid":"40e8dad1-ddd8-4a99-9b76-b64193479b4a","updated_by":"","created_by":"","updated_at":"2016-03-22T23:37:42.29114006Z","created_at":"2016-03-22T23:27:01.999395535Z","ports":[{"number":0,"optional":false,"routes":[{"type":"http","endpoint":"web1-3ps9to.tutorial.apcera-platform.io","weight":0}]}],"logs":[],"name":"web1","fqn":"job::/sandbox/admin::web1","num_instances":2,"packages":[],"processes":{},"resources":{"cpu":0,"memory":268435456,"disk":1073741824,"network":5000000,"netmax":0},"rollout":{"force_stop_old_instances_after":0,"flapping_minimum_restarts":0,"flapping_percent":0,"flapping_window":0,"errored_state_window":0},"restart":{"restart_mode":"always"},"state":"ready","tags":{"app":"web1"},"version_id":2,"network_ref":null,"aggregate_network_routes":null},{"uuid":"fe3b71e0-d8f8-42a1-8ce9-ff261549188b","updated_by":"","created_by":"","updated_at":"2016-03-22T23:27:08.284436233Z","created_at":"2016-03-22T23:27:08.284436233Z","ports":[{"number":0,"optional":false,"routes":[{"type":"http","endpoint":"web2-pd03a0.tutorial.apcera-platform.io","weight":0}]}],"logs":[],"name":"web2","fqn":"job::/sandbox/admin::web2","num_instances":2,"packages":[],"processes":{},"resources":{"cpu":0,"memory":268435456,"disk":1073741824,"network":5000000,"netmax":0},"rollout":{"force_stop_old_instances_after":0,"flapping_minimum_restarts":0,"flapping_percent":0,"flapping_window":0,"errored_state_window":0},"restart":{"restart_mode":"always"},"state":"ready","tags":{"app":"web2"},"version_id":1,"network_ref":null,"aggregate_network_routes":null}]