Axcient x360Recover API and MCP fundamentals: x-api-key header authentication, the single production base URL, the full 20-tool MCP catalog by domain, why most list endpoints return bare arrays with no pagination, and the five distinct error response shapes the upstream API actually returns.
Scanned 9/5/2026
Install to Claude Code
npx -y skills add WYRE-AI/msp-claude-plugins --skill api-patterns --agent claude-codeInstalls into .claude/skills of the current project.
Are you the author of Api Patterns?
Add the live security badge to your README — it updates automatically with every re-scan.
[](https://www.skillsdirectory.com/skills/wyre-ai-api-patterns-02e8d685)More formats (shields.io, HTML) on the badges page.
---
name: "Axcient API Patterns"
description: >
Axcient x360Recover API and MCP fundamentals: x-api-key header
authentication, the single production base URL, the full 20-tool MCP
catalog by domain, why most list endpoints return bare arrays with no
pagination, and the five distinct error response shapes the upstream API
actually returns.
when_to_use: >-
When authenticating to or calling the Axcient x360Recover API directly or
through the MCP tools, or when discovering which Axcient tool to use. Use
when: axcient api, axcient authentication, axcient pagination, axcient mcp,
axcient tools, axcient request, axcient error, axcient connection, or
x360recover api.
---
# Axcient MCP Tools & API Patterns
## Overview
The Axcient MCP server wraps the x360Recover Public API (BCDR — backup
continuity and disaster recovery for servers and workstations behind Axcient
appliances, plus direct-to-cloud agents). It registers 20 tools covering the
caller's organization, clients, devices, backup jobs, vaults, and appliances.
Eighteen are read-only `GET` calls; two mutate state —
`axcient_set_vault_threshold` and `axcient_get_d2c_agent_token`.
## Anti-triggers
- **Datto BCDR (SIRIS/ALTO) devices** — different vendor, different API.
Use `datto-bcdr`.
- **Datto SaaS Protection (M365/Google Workspace backup)** — use
`datto-saas-protection`.
- **Unitrends appliances** — use `unitrends`.
- **Billing/usage reconciliation across the whole x360 suite** — Axcient's
separate Billing API is not wrapped by this server; nothing here returns
invoice line items.
## Connection & Authentication
### API Key Authentication
x360Recover authenticates with a single HTTP header:
| Header | Value |
|--------|-------|
| `x-api-key` | Your Axcient API key |
Generate credentials at: **partner.axcient.com > Settings > API Keys**
(any administrator can create one; all administrators can view and delete
keys created by others in the same organization).
**Environment Variables (self-hosted / stdio mode):**
```bash
export AXCIENT_API_KEY="your-api-key"
```
Through the WYRE Conduit gateway you set nothing — Conduit holds the key and
injects it per request as `X-Axcient-Api-Key`, which the server forwards
upstream as `x-api-key`. See `GOVERNANCE.md`.
> **IMPORTANT:** Never hardcode credentials.
### Base URL
```
https://axapi.axcient.com/x360recover
```
There is no region selection — one production host for all customers.
(Axcient also publishes a mock server at `ax-pub-recover.wiremockapi.cloud`
for testing without live credentials; this plugin's MCP server always talks
to production.)
## The call shape: client- and device-scoped, not flat
Devices, jobs, and appliances nest under a client (`client_id`), and jobs
additionally nest under a device (`device_id`). There are two ways to reach
devices and appliances: an org-wide list (`axcient_list_devices`,
`axcient_list_appliances`) or a client-scoped list
(`axcient_list_devices_by_client`, `axcient_list_appliances_by_client`).
Jobs have **no org-wide list** — you always need a `client_id` and
`device_id` in hand first, from a prior devices call.
All IDs are **integers**, not strings.
## Available MCP Tools
### Status & Organization
| Tool | Arguments | Description |
|------|-----------|-------------|
| `axcient_test_connection` | *(none)* | Server's Axcient connection/credential state |
| `axcient_get_organization` | *(none)* | The caller's own organization, resolved from the API key |
### Clients
| Tool | Arguments | Description |
|------|-----------|-------------|
| `axcient_list_clients` | `include_appliances?` | Every client visible to this credential |
| `axcient_get_client` | `client_id`, `include_appliances?` | One client, with health status and protected-system counters |
| `axcient_get_d2c_agent_token` | `client_id`, `vault_id` | Mints a direct-to-cloud agent enrollment token (POST, 201) |
### Devices
| Tool | Arguments | Description |
|------|-----------|-------------|
| `axcient_list_devices` | `limit?`, `offset?` | Every device across the organization |
| `axcient_list_devices_by_client` | `client_id`, `service_id?`, `d2c_only?` | Devices for one client |
| `axcient_get_device` | `device_id` | Full detail for one device |
| `axcient_get_device_autoverify` | `device_id` | Latest screenshot-verification (AutoVerify) results |
| `axcient_get_device_restore_points` | `device_id` | Available restore points for the device |
### Jobs
| Tool | Arguments | Description |
|------|-----------|-------------|
| `axcient_list_jobs_by_device` | `client_id`, `device_id` | All backup jobs for a device |
| `axcient_get_job` | `client_id`, `device_id`, `job_id` | One job |
| `axcient_get_job_history` | `client_id`, `device_id`, `job_id`, `limit?`, `offset?`, `starttime_begin?` | Run history for a job |
Jobs come in two shapes discriminated by the upstream schema — BRC
(appliance-based, legacy) and Replibit (current appliance OS). Both are
returned by the same tools; treat the response as a tagged union rather than
assuming one field set.
### Vaults
| Tool | Arguments | Description |
|------|-----------|-------------|
| `axcient_list_vaults` | `vault_type?` (`Private`\|`Cloud`), `active?`, `with_url?`, `limit?`, `include_devices?` | Every vault (private on-prem or Axcient cloud) |
| `axcient_get_vault` | `vault_id` | One vault |
| `axcient_get_vault_threshold` | `vault_id` | Current connectivity-loss alert threshold |
| `axcient_set_vault_threshold` | `vault_id`, `threshold` | **Changes** the connectivity-loss threshold (minutes) |
### Appliances
| Tool | Arguments | Description |
|------|-----------|-------------|
| `axcient_list_appliances` | `service_id?`, `include_devices?` | Every appliance in the organization |
| `axcient_list_appliances_by_client` | `client_id`, `include_devices?` | Appliances for one client |
| `axcient_get_appliance` | `appliance_id`, `include_devices?` | One appliance |
## Pagination
Only two endpoints accept pagination arguments: `axcient_list_devices`
(`limit`/`offset`) and `axcient_get_job_history` (`limit`/`offset`, plus
`starttime_begin` as a unix timestamp floor). Every other list tool returns
its complete result set in a single response — there is no cursor and no
`has_more` flag anywhere in this API. Client, appliance, and vault lists in
particular can return everything the credential can see in one call; do not
add a pagination loop where the tool signature doesn't accept one.
## Error Handling
x360Recover is a young public API (beta as of the current schema) and its
error responses are **not uniform** — the same conceptual failure can arrive
in different shapes depending on which layer rejects the request. The MCP
server normalizes all of these into a consistent `AxcientApiError`, but it's
worth knowing what's actually happening upstream:
| Situation | HTTP Status | Content-Type | Body shape |
|-----------|-------------|---------------|------------|
| Invalid API key | 401 | `application/json` | `{"message": "Unauthorized"}` |
| Invalid endpoint / bad path param (e.g. non-numeric ID) | 401 (not 400, despite the OpenAPI spec) | `text/html` | `{"code": 401, "msg": "Unauthorized"}` |
| Resource not found | 404 | `application/problem+json` | `{"detail", "status", "title", "type": "NotFoundException"}` |
| Bad request | 400 | `application/problem+json` | `{"detail", "status", "title", "type": "about:blank"}` |
| Insufficient permissions (mutating calls) | 403 | `application/problem+json` | `{"detail", "status", "title", "type": "ForbiddenException"}` |
**The practical consequence:** a malformed ID (e.g. passing a client's name
instead of its integer `client_id`) surfaces as a 401, identically to a bad
API key. If a single call fails with "unauthorized" but `axcient_test_connection`
confirms the credential works, the actual problem is almost always an
invalid path parameter, not a revoked key.
## Best Practices
- Resolve `client_id` and `device_id` from a list call before calling any
job tool — there is no way to reach a job without both ancestors in hand.
- Treat `axcient_get_device_restore_points` and `axcient_get_job_history`
as the two tools to reach for when a question is "did the backup actually
run", not the job's own `latest_*_rp` timestamps alone — a device can show
a recent local RP while its cloud/vault replication has stalled.
- `axcient_get_d2c_agent_token` returns short-lived enrollment
material for provisioning a *new* direct-to-cloud agent — it is not a way
to read an existing agent's credentials, and calling it does not affect
any device already enrolled.
- Cache `axcient_list_clients` and `axcient_list_appliances` results within
a session; they change far less often than device or job state.
## Related Skills
- [clients](../clients/SKILL.md) - Client health, protected-system counters, D2C enrollment
- [devices](../devices/SKILL.md) - Device inventory, AutoVerify, restore points
- [jobs](../jobs/SKILL.md) - Backup job status and run history
- [vaults](../vaults/SKILL.md) - Private/cloud vault state and connectivity thresholds
- [appliances](../appliances/SKILL.md) - Appliance inventory and hardware detail
Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.
No comments yet. Be the first to comment!