# Overview: SparkVault API Reference

> Build secure applications with post-quantum encryption. The SparkVault API provides programmatic access to encrypted vaults, ephemeral secrets, identity products, and integrations.

Canonical: https://sparkvault.com/api/docs/ · OpenAPI: https://sparkvault.com/openapi.yaml

## Quick Start

Every call is plain JSON over HTTPS, authenticated with an API key: [grab yours](https://app.sparkvault.com/api/keys), then seal your first secret. It burns the moment it's read:

```bash
curl https://api.sparkvault.com/v1/sparks \
  -H "X-API-Key: sv_test_YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"payload": "the launch code is 793-alpha", "ttl_minutes": 60}'
```

The response's `data.spark_id` is the one-time handle to your secret: [read it once](/api/docs/sparks/) and it's gone. The [Authentication](#authentication) and [Response Format](#response-format) sections below cover the envelope, or skip the plumbing and start from the [JavaScript SDK](/api/docs/sdk-js/).

## Explore the API

### Elements

- [Sparks](/api/docs/sparks/): Ephemeral secrets that burn on read (`/v1/sparks`) 
- [Vaults](/api/docs/vaults/): Triple zero-trust encrypted storage (`/v1/vaults`) 
- [Ingots](/api/docs/ingots/): Encrypted files, 1 byte to 5 TB (`/v1/vaults/{id}/ingots`) 
- [SparkLinks](/api/docs/sparklinks/): Trackable single-use share links (`/v1/sparklinks`) 
- [Entropy](/api/docs/entropy/): HSM-backed cryptographic randomness (`/v1/entropy`) 
- [Forge](/api/docs/forge/): Streaming AES-256-GCM for any file size (`forge.sparkvault.com`)

### [Products](/api/docs/products/)

- [Identity](/api/docs/products/identity/): OIDC IdP with passkeys, OTP, and social login 
- [Notify](/api/docs/products/notify/): Sealed notifications with cryptographic receipts 
- [Messaging](/api/docs/products/messaging/): Encrypted two-way threads with account-less recipients 
- [Structured Ingots](/api/docs/products/structured-ingots/): Encrypted key/value storage with atomic operations

### [Integrations](/api/docs/integrations/)

- [Slack](/api/docs/integrations/slack/): Self-destructing secrets via /secret (`/v1/apps/slack`) 
- [HubSpot](/api/docs/integrations/hubspot/): Encrypted files on every CRM record (`/v1/apps/hubspot`) 
- [Salesforce](/api/docs/integrations/salesforce/): Encrypted files on Accounts, Opportunities, Cases (`/v1/apps/salesforce`)

### Platform

- [Authentication](/api/docs/authentication/): API keys and JWTs (`X-API-Key`) 
- [API Keys](https://app.sparkvault.com/api/keys): Create and manage keys in the app (`app.sparkvault.com`) 
- [Reporting](/api/docs/reporting/): Usage metrics, analytics, and activity (`/v1/analytics`) 
- [Audit Logs](/api/docs/audit-logs/): Security and operational events (`/v1/audit-logs`) 
- [JavaScript SDK](/api/docs/sdk-js/): Browsers and Node.js (`@sparkvault/sdk-js`) 
- [Mobile SDK](/api/docs/sdk-mobile/): React Native and Expo (`@sparkvault/sdk-mobile`)

## Base URL

All API requests should be made to the following base URL:

```text
https://api.sparkvault.com/v1
```

> **HTTPS Required**
>
> All API requests must be made over HTTPS. Requests over plain HTTP will be rejected.

## Authentication

SparkVault supports two authentication methods:

-   **API Keys**: Best for server-to-server integrations and automation. Keys are prefixed `sv_live_` (production) or `sv_test_` (test).
-   **JWT Tokens**: Best for user-facing applications with session management

Include your API key in the `X-API-Key` header:

```bash
curl https://api.sparkvault.com/v1/sparks \
  -H "X-API-Key: sv_live_YOUR_API_KEY"
```

> **Vault Access Tokens**
>
> Vault operations additionally require an `X-Vault-Access-Token: {vat}` header, issued when you unseal the vault. See the [Vaults API](/api/docs/vaults/) for details.

See the [Authentication guide](/api/docs/authentication/) for complete details.

## Response Format

All successful responses follow a consistent JSON structure with `data` and `meta` fields:

```json
{
  "data": {
    "spark_id": "spk_abc123...",
    "account_id": "acc_def456...",
    "content_type": "text/plain",
    "size_bytes": 1024,
    "status": "active",
    "created_at": 1702000000,
    "expires_at": 1702003600,
    "burned_at": null,
    "time_remaining": 3600
  },
  "meta": {
    "api_version": "1.x.y",
    "request_id": "req_xyz789...",
    "response_ms": 42,
    "timestamp": 1702000000,
    "pools": {
      "storage": { "used_gb": 12.5, "limit_gb": 100, "pct": 0.125, "state": "ok" },
      "bandwidth": { "used_gb": 3.25, "limit_gb": 100, "pct": 0.0325, "state": "ok", "cycle_resets_at": 1704067200 },
      "identity": { "used": 15, "limit": 500, "pct": 0.03, "state": "ok" }
    },
    "quota": {
      "limit": 300,
      "used": 15,
      "remaining": 285,
      "resets_at": 1702000060
    }
  }
}
```

#### Meta Fields

-   `api_version`: Semantic version of the deployed API release
-   `request_id`: Unique identifier for this request (useful for support)
-   `response_ms`: Server processing time in milliseconds
-   `timestamp`: Unix timestamp when response was generated
-   `pools`: Pooled-capacity status for your subscription's storage, bandwidth, and identity pools, attached only on authenticated, successful responses to billable routes. Each pool reports usage against its limit, a utilization fraction (`pct`), and a `state` of `ok` | `notice` | `warning` | `exhausted`. This is usage tracking, not a spendable balance.
-   `quota`: Rate limit status for your account (included on authenticated responses with status below 400)

## Error Handling

Errors return a consistent structure with machine-readable codes and human-friendly messages:

```json
{
  "error": {
    "code": "VALIDATION_ERROR",
    "message": "The 'name' field is required",
    "details": {
      "field": "name",
      "reason": "missing"
    }
  },
  "meta": {
    "api_version": "1.x.y",
    "request_id": "req_xyz789..."
  }
}
```

#### Common Error Codes

| Status | Code | Description |
| --- | --- | --- |
| 400 | `VALIDATION_ERROR` | Invalid request parameters or body |
| 401 | `AUTHENTICATION_ERROR` | Missing or invalid authentication credentials |
| 401 | `UNAUTHORIZED` | Presented token, grant, or key is invalid, expired, or revoked |
| 402 | `PLAN_REQUIRED` | An active subscription is required for this operation |
| 402 | `QUOTA_EXCEEDED` | A pooled-capacity or seat limit is reached (`details.resource` is `storage`, `bandwidth`, `seats`, or `identity`). `details.action_required` indicates which add-on or seat amendment unblocks you |
| 403 | `FORBIDDEN` | Valid credentials but insufficient permissions |
| 404 | `NOT_FOUND` | Requested resource does not exist |
| 404 | `UPLOAD_SOURCE_DISABLED` | Vault exists but the requested upload source (portal or embedded widget) is not enabled on it |
| 409 | `CONFLICT` | Resource conflict (e.g., duplicate name) |
| 412 | `PRECONDITION_FAILED` | A required precondition was not met (e.g., invalid VMK) |
| 413 | `PAYLOAD_TOO_LARGE` | Request body or upload exceeds the size limit |
| 429 | `RATE_LIMIT_EXCEEDED` | Too many requests, slow down |
| 500 | `INTERNAL_ERROR` | Unexpected server error (contact support) |

## Rate Limiting

API requests are rate limited to **300 requests per minute** per account, measured in 60-second windows. The current rate limit status is included in the `meta.quota` field of every authenticated response with a status below 400.

```json
{
  "meta": {
    "quota": {
      "limit": 300,
      "used": 42,
      "remaining": 258,
      "resets_at": 1702000060
    }
  }
}
```

> **Rate Limit Exceeded**
>
> When you exceed the rate limit, requests return `429 Too Many Requests` with a `Retry-After` header set to the number of seconds until the window resets. The error's `details` include `limit`, `used`, and `resets_at` so you know when your quota resets.

## Pagination

List endpoints use cursor-based pagination with `limit` and `cursor` query parameters. Cursors are signed per account and bound to the resource they page over. A tampered, cross-account, or cross-resource cursor returns `400 VALIDATION_ERROR`.

```bash
curl "https://api.sparkvault.com/v1/sparks?limit=20&cursor=eyJzcGFya19pZCI6..." \
  -H "X-API-Key: sv_live_YOUR_API_KEY"
```

Paginated responses include the items, a `count`, and cursor metadata:

```json
{
  "data": {
    "sparks": [...],
    "count": 20,
    "has_more": true,
    "next_cursor": "eyJzcGFya19pZCI6..."
  }
}
```

`next_cursor` is present only when `has_more` is `true`. Pass it back as the `cursor` parameter to fetch the next page. A `total` field appears only on endpoints that compute one. Default and maximum `limit` vary per endpoint (default 25-100, max 100-500); check each endpoint's reference page for exact values. For example, `/sparks` and `/vaults` both default to 100 (max 500).

## Security

> **Post-Quantum Encryption**
>
> SparkVault uses ML-KEM-1024 (CRYSTALS-Kyber) for key encapsulation and AES-256-GCM for data encryption. This provides protection against both classical and quantum computer attacks.

#### Zero-Knowledge Architecture

SparkVault is designed so that we **cannot access your encrypted data**, even with full system access. Our multi-key architecture uses three types of master keys:

-   **SparkVault Master Key (SVMK)**: SparkVault's system-wide software ML-KEM-1024 keypair, stored in AWS SSM Parameter Store
-   **Account Master Key (AMK)**: Your account's unique HMAC key managed in AWS KMS (FIPS 140-3 validated)
-   **Vault Master Key (VMK)**: A per-vault key that you generate and control

Different features require different combinations of these keys:

-   **Sparks (Double Zero-Trust)**: Requires both the SVMK and your AMK
-   **Vaults (Triple Zero-Trust)**: Requires the SVMK, AMK, and your VMK

#### Key Management

Self-managed Vault Master Keys (VMKs) are generated client-side and are **never stored** by SparkVault. If you lose a self-managed VMK, the data in that vault is permanently unrecoverable, so always store it in a secure password manager or key management system. Vaults using the **Hosted VMK** option instead store the VMK KMS-wrapped (a per-vault key under the HVMK root KEK), which lets SparkVault derive vault access server-side for features like public sharing.

## Client Libraries

Official SDKs handle authentication, encryption, and resumable transfers for you:

-   **[JavaScript SDK](/api/docs/sdk-js/)**: `@sparkvault/sdk-js` for browsers and Node.js
-   **[Mobile SDK](/api/docs/sdk-mobile/)**: `@sparkvault/sdk-mobile` for React Native and Expo

For other languages, any HTTP client works: the API is plain JSON over HTTPS.

## Support

Need help? Include the `request_id` from the response when contacting support. This helps us quickly locate your request in our logs.

-   **Email:** support@sparkvault.com
