Skip to content

API Keys

API keys are long-lived credentials that grant programmatic access to the Arrow REST API, scoped to a single organization. They allow external tools and scripts to interact with Arrow without requiring a user session or browser login.

When to use API keys:

  • Automation scripts (Bash, Python, PowerShell)
  • CI/CD pipelines
  • Ansible playbooks and configuration management
  • Monitoring and inventory tools
  • Custom integrations with internal systems

When to use the web UI instead:

  • Day-to-day manual operations such as creating device requests, reviewing shipments, or managing users

Org Admins and Site Admins (for their own organization) can create and manage API keys. Site admins without an organization must use admin impersonation to manage keys for other organizations.

  1. Sign in and click API Keys in the sidebar (requires the api_keys.manage permission or site admin status).
  2. Click Create API Key.
  3. Enter a descriptive Key Name (e.g., Ansible Automation).
  4. Select one or more Scopes (see the table below).
  5. Choose an Expiration — presets: 30 days, 90 days, 180 days, 1 year; or pick a custom date. Maximum is 1 year from today; expiration is required.
  6. Click Create Key.
  7. Copy the secret immediately — it is shown only once. Store it in a secrets manager or environment variable.

Important: The full API key secret is displayed only once at creation time. Arrow stores only a hash of the key and cannot retrieve the original value.

ScopeGrants Access To
devices:readList and view devices in your organization
devices:writeUpdate device settings and tags
device_requests:readList and view device requests
device_requests:writeCreate, update, and extend device requests; mark VM requests as returned
clients:readList and view clients in your organization
clients:writeCreate, update, and delete clients
users:readList and view organization users
metrics:readView organization metrics and statistics
billing:readView invoices, charges, and billing information

Follow the principle of least privilege — only select the scopes your integration actually needs.

Every API request must include the key in the X-API-Key HTTP header.

curl example:

Terminal window
curl -H "X-API-Key: arrow_YOUR_KEY_HERE" \
https://arrow.vtemlabs.com/api/v1/devices

Python example:

import os
import requests
API_KEY = os.environ["ARROW_API_KEY"]
BASE_URL = "https://arrow.vtemlabs.com"
resp = requests.get(
f"{BASE_URL}/api/v1/devices",
headers={"X-API-Key": API_KEY},
)
resp.raise_for_status()
devices = resp.json()

Interactive API Documentation Explore and test all available endpoints in the Swagger UI. No login required — just paste your API key into the Authorize button.

MethodEndpointScope RequiredDescription
GET/api/v1/devicesdevices:readList all devices in your org (paginated)
GET/api/v1/devices/{id}devices:readGet a single device
PATCH/api/v1/devices/{id}devices:writeUpdate device tags or notes
MethodEndpointScope RequiredDescription
GET/api/v1/device-requestsdevice_requests:readList device requests (supports ?device_type= filter)
GET/api/v1/device-requests/{id}device_requests:readGet a single device request
POST/api/v1/device-requestsdevice_requests:writeCreate a new device request
PATCH/api/v1/device-requests/{id}device_requests:writeUpdate details or extend dates
POST/api/v1/device-requests/{id}/mark-vm-returneddevice_requests:writeMark a VM request as returned/decommissioned

Note: The mark-vm-returned endpoint applies only to VM device requests. Physical device returns are tracked automatically via EasyPost shipping webhooks when the carrier scans the return package — no API call is needed. VM deployments have no physical shipment, so this endpoint lets automation signal that the VM has been destroyed.

MethodEndpointScope RequiredDescription
GET/api/v1/clientsclients:readList all clients in your organization
GET/api/v1/clients/{id}clients:readGet a single client
POST/api/v1/clientsclients:writeCreate a new client
PATCH/api/v1/clients/{id}clients:writeUpdate client details
DELETE/api/v1/clients/{id}clients:writeDelete a client
MethodEndpointScope RequiredDescription
GET/api/v1/usersusers:readList all users in your organization
GET/api/v1/users/{id}users:readGet a single user
MethodEndpointScope RequiredDescription
GET/api/v1/metricsmetrics:readGet organization metrics and statistics
MethodEndpointScope RequiredDescription
GET/api/v1/billing/invoicesbilling:readList invoices for your organization
GET/api/v1/billing/invoices/{id}billing:readGet a single invoice
GET/api/v1/billing/chargesbilling:readGet current billing charges
  • Store keys in environment variables — never hard-code them in source files or commit them to version control.
  • Use minimal scopes — grant only the scopes your integration requires.
  • Rotate before expiry — create a replacement key before the current one expires to avoid downtime. The UI shows a warning badge 14 days before expiry.
  • Respect the 1-year maximum — keys cannot be created without an expiration date; the maximum lifetime is 365 days.
  • Revoke unused keys immediately — if a key is no longer needed or may have been exposed, revoke it right away.
  1. Click API Keys in the sidebar.
  2. Find the key you want to revoke in the table.
  3. Click the actions menu (three dots) and select Revoke.
  4. Confirm the revocation in the dialog.

Note: Revocation is immediate. Any request using the revoked key will receive a 401 Unauthorized response.