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.

FieldTypeDescription
emailstring, requiredCustomer email; the ARK Care account is keyed on this.
namestringCustomer full name.
phonestringCustomer phone (UK).
slugstring, requiredProduct slug from /products.
quantitynumberDefaults to 1.
addOnsarray[{ "slug": "backup-extra-device", "quantity": 2 }] — same billing interval as the main plan.
remoteSetupbooleanAdds the one-off Remote Setup fee (monthly plans only; free on annual).
uiMode"hosted" | "embedded"Defaults to hosted.
successUrlstring (https)Where the customer lands after paying. Must be an allowed origin.
cancelUrlstring (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

  1. Cache GET /products to render plan/extra options in your basket.
  2. Optionally call GET /customer with the buyer's email to avoid selling a duplicate plan.
  3. At the end of your checkout, POST /checkout and send the customer to the Stripe URL (or render the embedded form).
  4. On your thank-you page, read session_id from the URL and call GET /order before showing confirmation.