ARK Care Partner API
Sell ARK Care plans and extras (managed antivirus, cloud backup, VPN) from your own website or webshop. ARK Care takes the payment, creates the customer's account and provisions everything automatically.
Getting access
Every request needs an API key, sent either as the x-ark-api-key header or as Authorization: Bearer <key>. Keys are issued by ARK Care and can be restricted to specific website origins — browser calls and the checkout success/cancel URLs must come from an allowed origin. To get a key, email support@arkcare.uk or call 01329 623 555.
Base URL: https://arkcare.uk/api/public/shop. All amounts are in the smallest currency unit (pence). CORS is enabled for the origins registered against your key.
Endpoints
GET/products
Lists everything you can sell. No parameters.
GET https://arkcare.uk/api/public/shop/products
x-ark-api-key: <your key>
→ 200 {
"products": [
{
"slug": "care-shield",
"name": "ARK Care Shield",
"description": "…",
"category": "care", // care | backup | antivirus | vpn
"billingInterval": "month", // month | year
"unitAmount": 999, // pence
"currency": "gbp",
"includedDevices": 1,
"includedStorageGb": null
}
]
}GET/customer
Optional pre-check: does this email already hold ARK Care plans? Useful to suggest add-ons rather than duplicates. Pass ?email=.
GET https://arkcare.uk/api/public/shop/customer?email=jane@example.com
x-ark-api-key: <your key>
→ 200 {
"exists": true,
"activePlans": [
{ "name": "ARK Care Plus", "slug": "care-plus",
"category": "care", "billingInterval": "month", "status": "active" }
]
}POST/checkout
Starts a Stripe checkout for one plan plus optional extras. If the email has no ARK Care account one is created automatically (accountCreated tells you). Two modes: hosted redirects the customer to a Stripe-hosted page; embedded returns a client secret so you can render Stripe's embedded checkout on your own page.
| Field | Type | Description |
|---|---|---|
| string, required | Customer email; the ARK Care account is keyed on this. | |
| name | string | Customer full name. |
| phone | string | Customer phone (UK). |
| slug | string, required | Product slug from /products. |
| quantity | number | Defaults to 1. |
| addOns | array | [{ "slug": "backup-extra-device", "quantity": 2 }] — same billing interval as the main plan. |
| remoteSetup | boolean | Adds the one-off Remote Setup fee (monthly plans only; free on annual). |
| uiMode | "hosted" | "embedded" | Defaults to hosted. |
| successUrl | string (https) | Where the customer lands after paying. Must be an allowed origin. |
| cancelUrl | string (https) | Where the customer lands if they abandon checkout. |
POST https://arkcare.uk/api/public/shop/checkout
x-ark-api-key: <your key>
content-type: application/json
{
"email": "jane@example.com",
"name": "Jane Smith",
"phone": "07700 900123",
"slug": "backup-500",
"addOns": [ { "slug": "backup-extra-device", "quantity": 2 } ],
"remoteSetup": true,
"uiMode": "hosted",
"successUrl": "https://your-shop.example/thank-you",
"cancelUrl": "https://your-shop.example/basket"
}
→ 200 (hosted) { "sessionId": "cs_…", "url": "https://checkout.stripe.com/…",
"accountCreated": true, "testMode": false }
→ 200 (embedded) { "sessionId": "cs_…", "clientSecret": "…",
"publishableKey": "pk_…", "accountCreated": true }Hosted mode: redirect the customer to url. Embedded mode: mount Stripe's embedded checkout with clientSecret; after payment Stripe returns the customer to your successUrl with ?session_id=cs_… appended.
GET/order
Confirms the order on your thank-you page. Pass the ?session_id= Stripe appended to your success URL.
GET https://arkcare.uk/api/public/shop/order?session_id=cs_…
x-ark-api-key: <your key>
→ 200 {
"status": "complete",
"payment_status": "paid",
"paid": true,
"email": "jane@example.com",
"amountTotal": 1499,
"currency": "gbp",
"planName": "ARK Backup 500GB",
"portalUrl": "https://arkcare.uk/portal"
}Cover & entitlements (v1)
For workshop and counter systems that need to know what a customer is covered for before pricing a job. Same API key and origin rules; base URL https://arkcare.uk/api/public/v1. These endpoints never return personal details — identity is pushed to you by webhook instead.
GET/v1/health
Key and service check.
→ 200 { "ok": true, "service": "ark-care", "version": "v1", "time": "…" }GET/v1/customers
Everything about one customer in a single call. Pass ?email=.
→ 200 {
"exists": true,
"customerId": "uuid",
"opsHubCustomerId": "…or null",
"plans": [ { "subscriptionId": "uuid", "name": "ARK Care Plus", "slug": "care-plus",
"category": "care", "billingInterval": "month", "status": "active",
"quantity": 1, "extraDevices": 2, "currentPeriodEnd": "2026-10-01T…" } ],
"entitlements": [ { "id": "uuid", "kind": "free_repair_support", "expiresAt": null } ],
"devices": { "included": 3, "managed": 2 }
}GET/v1/subscriptions
Active cover only, in detail. ?email=.
GET/v1/entitlements
Unused included sessions and credits. ?email=.
GET/v1/devices
Managed devices: id, hostName, os, onlineStatus, antivirusStatus, lastSeenAt. ?email=.
POST/v1/entitlements/consume
Redeem one included session against a job. Idempotent on reference — replaying the same job id will not burn a second credit.
{ "email": "jane@example.com", "kind": "free_repair_support",
"reference": "OPSHUB-JOB-1234" }
→ 200 { "consumed": true, "replayed": false,
"entitlement": { "id": "uuid", "kind": "free_repair_support" }, "remaining": 0 }
→ 409 { "consumed": false, "reason": "no-entitlement", "available": [] }Webhooks we send you
When cover starts, changes, is cancelled or a payment fails, we POST a JSON event to your endpoint with the customer's identity so you can create or update their record. The body is signed: x-arkcare-signature: sha256=<hex HMAC of the raw body> using a shared secret. Verify it before trusting the payload and answer 2xx quickly; we retry nothing, but every event is also derivable from the v1 endpoints above.
POST <your base>/api/public/v1/hooks/arkcare
x-arkcare-signature: sha256=…
x-arkcare-event: subscription.started
{
"event": "subscription.started", // started | changed | cancelled | payment_failed
"occurredAt": "2026-09-07T21:04:11.000Z",
"customer": { "email": "jane@example.com", "name": "Jane Smith",
"phone": "07700 900123", "company": null, "opsHubCustomerId": null },
"plan": { "slug": "care-plus", "name": "ARK Care Plus", "category": "care",
"billingInterval": "month", "quantity": 1, "extraDevices": 2,
"status": "active", "currentPeriodEnd": "2026-10-07T…" }
}Errors
Errors return JSON { "error": "…" } with a suitable status: 401 missing/revoked key, 403 origin not allowed, 400 invalid body or unknown slug, 404 unknown session, 500 something on our side (safe to retry after a moment).
Typical webshop flow
- Cache
GET /productsto render plan/extra options in your basket. - Optionally call
GET /customerwith the buyer's email to avoid selling a duplicate plan. - At the end of your checkout,
POST /checkoutand send the customer to the Stripe URL (or render the embedded form). - On your thank-you page, read
session_idfrom the URL and callGET /orderbefore showing confirmation.