# Integrations: SparkVault API Reference

> Installable, OAuth-connected, per-account integrations that connect SparkVault to external systems: Slack, HubSpot, and Salesforce.

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

## Overview

Integrations are installable, OAuth-connected, per-account additions that connect SparkVault to external systems. They are distinct from global [Products](/api/docs/products/), which are always available and never require installation, and from platform Elements (Entropy, Sparks, SparkLinks, Vaults, Ingots), which are the primitives everything else composes over.

[

### Slack

Send self-destructing secrets directly in Slack with the `/secret` command. Post-quantum encrypted, burn-after-read.

](/api/docs/integrations/slack/)[

### HubSpot

Encrypted file storage on HubSpot CRM records: a SparkVault Files tab on every Contact, Company, Deal, and Ticket.

](/api/docs/integrations/hubspot/)[

### Salesforce

Encrypted file storage on Salesforce CRM records: a SparkVault Files panel on every Account, Contact, Opportunity, and Case.

](/api/docs/integrations/salesforce/)

> **OAuth required**
>
> All three integrations connect to an external service and require an OAuth authorization on that service before they are active. Install them from [app.sparkvault.com/integrations](https://app.sparkvault.com/integrations), or see the [OAuth Install Flow](#oauth-install-flow) below.

## Why Use Integrations?

#### Zero Cryptographic Expertise Required

No key management or protocol work. Slack secrets are burn-after-read Sparks sealed with post-quantum encryption (ML-KEM-1024). HubSpot and Salesforce files are protected with Triple Zero-Trust encryption via [Forge](/api/docs/forge/). Install, connect, and use.

#### Tenant and Record Isolation by Design

The CRM integrations serve many portal/org users against one shared installation without ever sharing access: vault unseals mint per-user VAT sessions keyed to the verified CRM user, and every download or delete is verified against the requesting record's folder, enforcing per-record isolation within a tenant.

#### Predictable Pricing

Slack uses standard Spark pricing: $0.001 per secret sent, free to read. HubSpot and Salesforce add no per-operation fees; standard vault storage and transfer pricing applies.

#### Fully Audited

Every integration operation is logged with timestamp, account, parameters, and result status. Retrieve integration-scoped audit logs with `GET /v1/audit-logs/apps/:app_slug`; Slack additionally exposes usage analytics at `GET /v1/apps/slack/analytics`.

## Authentication

Integration endpoints authenticate on three planes:

| Plane | Endpoints | Authentication |
| --- | --- | --- |
| **Management** | List, get, install, update, and uninstall (`/v1/apps`, `/v1/apps/:app_id`) | Standard SparkVault auth: JWT session or `X-API-Key` header. Install, update, and uninstall require an **admin or owner** role. |
| **Provider webhooks** | Each integration's webhook routes | Signature-verified per provider: Slack `X-Slack-Signature`, HubSpot signature v3, Salesforce session bearer. |
| **CRM proxy** | HubSpot/Salesforce `resolve`, `files`, `unseal`, `download`, `delete-file` (Salesforce also `upload-context`) | Provider context: HubSpot-signed requests resolved by `portal_id` lookup; Salesforce session bearer verified against the installed org. |

Installed integrations use **pass-through authentication**: your JWT session or API key flows from user to integration to core API. There is no integration-specific credential binding to manage.

> **API Keys**
>
> Create and manage API keys from the [API Keys](https://app.sparkvault.com/api/keys) page. Use separate keys for different environments and integrations.

> **Looking for Secure Entropy?**
>
> Entropy is a platform Element: FIPS 140-3 validated, HSM-backed randomness available to every account without installation. See the [Entropy API documentation](/api/docs/entropy/).

## Response Format

All integration endpoints follow the standard SparkVault response format:

```json
{
  "data": {
    // Integration-specific response fields
  },
  "meta": {
    "api_version": "1.2.828",
    "request_id": "req_a1b2c3d4e5f6",
    "response_ms": 42,
    "timestamp": 1783036800
  }
}
```

Authenticated success responses also carry `meta.quota`: your account's current rate-limit status (see [Rate Limits](#rate-limits)).

```json
{
  "error": {
    "code": "VALIDATION_ERROR",
    "message": "Invalid app_id"
  },
  "meta": {
    "api_version": "1.2.828",
    "request_id": "req_a1b2c3d4e5f6"
  }
}
```

## Install Lifecycle API

Integrations are installed per account and managed through the `/v1/apps` endpoints. All five require standard SparkVault authentication (JWT or API key); install, update, and uninstall additionally require an **admin or owner** role.

#### `GET /v1/apps`

List the account's installed integrations plus the ids of every integration available in the catalog.

#### Response Fields

| Field | Type | Description |
| --- | --- | --- |
| `installed` | array | Installed integrations, each with `app_id`, `status`, `installed_at` (Unix epoch seconds), and `settings`. |
| `available` | array | Ids of all integrations in the catalog: `slack`, `hubspot`, `salesforce`. |

#### List integrations

Request

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

Response

```json
{
  "data": {
    "installed": [
      {
        "app_id": "slack",
        "status": "active",
        "installed_at": 1783036800,
        "settings": {}
      }
    ],
    "available": ["slack", "hubspot", "salesforce"]
  }
}
```

#### `GET /v1/apps/:app_id`

Get installation status and catalog details for a single integration. An uninstalled integration returns installed: false with status not_installed, not a 404.

#### Response Fields

| Field | Type | Description |
| --- | --- | --- |
| `app_id` | string | Integration id (`slack`, `hubspot`, or `salesforce`). |
| `name` | string | Display name from the catalog. |
| `description` | string | Catalog description. |
| `category` | string | Always `integrations`. |
| `features` | array | Catalog feature list. |
| `pricing` | object | Pricing summary: per-operation entries (`operations`) and a human-readable `description`. |
| `oauth_required` | boolean | Whether the integration requires an OAuth authorization on the external service. `true` for all three. |
| `installed` | boolean | Whether the integration is installed for this account. |
| `status` | string | `active` when installed; `not_installed` otherwise. |
| `settings` | object | The installation's settings. Present when installed. |
| `installed_at` | integer | Install time (Unix epoch seconds). Present when installed. |
| `account` | object | Account branding for customer-facing surfaces: `organization_name`, `logo_url_light`, `logo_url_dark`. |

#### `POST /v1/apps/:app_id`

Install an integration for the account. Requires an admin or owner role. Returns 201 with the installation merged over the catalog entry. Reinstalling a previously uninstalled integration reactivates it.

#### Body Parameters

| Parameter | Type | Required | Description |
| --- | --- | --- | --- |
| `settings` | object | Optional | Initial integration settings.Default: `{}` |
| `remote_id` | string | Optional | External workspace binding (e.g. a Slack `team_id`). A remote workspace can be bound to only one active account. Installing with an already-claimed id is rejected. |

> **OAuth-connected integrations install via their callback**
>
> All three catalog integrations set `oauth_required`. In practice they are installed through the [OAuth Install Flow](#oauth-install-flow), which validates the provider grant and then creates the installation. A bare install call does not connect the external service.

#### `PUT /v1/apps/:app_id`

Update an installed integration's settings. Requires an admin or owner role. Settings are merged into the installation's existing settings object.

#### Body Parameters

| Parameter | Type | Required | Description |
| --- | --- | --- | --- |
| `settings` | object | Required | Settings to merge into the installation's existing settings. |
| `remote_id` | string | Optional | Change the external workspace binding. Subject to the same one-active-account rule as install. |

#### `DELETE /v1/apps/:app_id`

Uninstall an integration. Requires an admin or owner role. Returns 204 No Content. The installation is soft-deleted and can be reactivated by reinstalling. Blocked while another installed integration depends on it.

#### Error Responses

| Status | Code | Description |
| --- | --- | --- |
| 400 | `VALIDATION_ERROR` | Invalid `app_id`, missing `settings` on update, or an unmet install dependency |
| 403 | `FORBIDDEN` | Caller is not an admin or owner (install, update, uninstall) |
| 404 | `NOT_FOUND` | Unknown integration id, or updating/uninstalling an integration that is not installed |
| 409 | `CONFLICT` | Integration is already installed |

## OAuth Install Flow

Every integration requires an OAuth authorization on the external service. The flow is the same for all three:

1.  **Authorize on the provider**: Start the install from [app.sparkvault.com/integrations](https://app.sparkvault.com/integrations). You are redirected to the provider's consent screen.
2.  **Exchange the code**: After the provider redirects back, the frontend posts the authorization code to the integration's OAuth callback under your SparkVault session (JWT): `POST /v1/apps/{slack|hubspot|salesforce}/oauth/callback` with `{ code, redirect_uri }`. The CRM integrations additionally send the selected `vault_id` and the installing user's `sv_refresh_token`; see each integration's page for the full callback body.
3.  **Server-side validation**: The backend exchanges the code with the provider and validates the grant. Slack requires the `commands` and `chat:write` bot scopes and is workspace-scoped. Org-wide Enterprise Grid installs are rejected. HubSpot and Salesforce verify the selected vault's ownership server-side with the caller's own token, so an installation can never bind to someone else's vault.
4.  **Installation created**: On success the installation is created. Slack and Salesforce re-authorize an existing active install in place with a fresh token set (the recovery path for a revoked or expired connection); HubSpot requires uninstalling before reinstalling.

#### Slack OAuth callback

Request

```bash
curl -X POST https://api.sparkvault.com/v1/apps/slack/oauth/callback \
  -H "Authorization: Bearer eyJhbGciOiJSUzI1NiIs..." \
  -H "Content-Type: application/json" \
  -d '{
    "code": "slack_oauth_code",
    "redirect_uri": "https://app.sparkvault.com/apps/slack/oauth/callback"
  }'
```

Response

```json
{
  "data": {
    "installed": true,
    "team_id": "T0123456789",
    "team_name": "Acme Corp",
    "account_id": "acc_xyz789..."
  }
}
```

#### Uninstalling

Each integration uninstalls two ways: user-initiated via `DELETE /v1/apps/{app_id}/uninstall` (JWT or API key), or automatically via provider webhook: Slack `app_uninstalled`/`tokens_revoked`, HubSpot `app.deauthorize`, Salesforce `app.uninstall`.

## Available Integrations

### Slack

Send self-destructing secrets directly in Slack with the `/secret` command.

-   `/secret` slash command
-   Send to users, groups, or channels
-   Post-quantum encryption (ML-KEM-1024)
-   Burn-after-read guarantee
-   Configurable expiration (1 minute to 24 hours)
-   Usage analytics by Slack user

**Pricing**: Standard Spark pricing ($0.001 per secret sent, free to read).

| Method | Path | Purpose | Auth |
| --- | --- | --- | --- |
| POST | `/v1/apps/slack/webhooks/commands` | Slash command handler | Slack signature |
| POST | `/v1/apps/slack/webhooks/interactions` | Button/modal interactions | Slack signature |
| POST | `/v1/apps/slack/webhooks/events` | Slack Events API | Slack signature |
| POST | `/v1/apps/slack/oauth/callback` | OAuth install callback | JWT or API key |
| DELETE | `/v1/apps/slack/uninstall` | User-initiated uninstall | JWT or API key |
| GET | `/v1/apps/slack/analytics` | Usage analytics | JWT or API key |

[View full Slack documentation →](/api/docs/integrations/slack/)

### HubSpot

Encrypted file storage on HubSpot CRM records. Access vault files directly from Contact, Company, Deal, and Ticket tabs.

-   SparkVault Files tab on CRM records
-   Folder-per-record organization (Contacts, Companies, Deals, Tickets)
-   Triple Zero-Trust encryption via Forge
-   Vault unseal via VMK, DVAK, or SparkSync mobile
-   Upload, download, and delete files from HubSpot

**Pricing**: Standard vault storage and transfer pricing applies. No additional per-operation fees.

| Method | Path | Purpose | Auth |
| --- | --- | --- | --- |
| POST | `/v1/apps/hubspot/resolve` | Map CRM record to vault + folder | HubSpot v3 signature + portal\_id lookup |
| POST | `/v1/apps/hubspot/files` | List files in a CRM record's folder | HubSpot v3 signature + portal\_id lookup |
| POST | `/v1/apps/hubspot/unseal` | Unseal vault with VMK/DVAK | HubSpot v3 signature + portal\_id lookup |
| POST | `/v1/apps/hubspot/download` | Get Forge URL for file download | HubSpot v3 signature + portal\_id lookup |
| POST | `/v1/apps/hubspot/delete-file` | Delete a file from the vault | HubSpot v3 signature + portal\_id lookup |
| POST | `/v1/apps/hubspot/oauth/callback` | OAuth install + server-verified vault selection | JWT or API key |
| DELETE | `/v1/apps/hubspot/uninstall` | User-initiated uninstall | JWT or API key |
| POST | `/v1/apps/hubspot/webhooks` | HubSpot webhook events | HubSpot signature v3 |

[View full HubSpot documentation →](/api/docs/integrations/hubspot/)

### Salesforce

Encrypted file storage on Salesforce CRM records. Access vault files directly from Account, Contact, Opportunity, and Case pages.

-   SparkVault Files panel on CRM records
-   Folder-per-record organization (Accounts, Contacts, Opportunities, Cases)
-   Triple Zero-Trust encryption via Forge
-   Vault unseal via VMK, DVAK, or SparkSync mobile
-   Upload, download, and delete files from Salesforce

**Pricing**: Standard vault storage and transfer pricing applies. No additional per-operation fees.

| Method | Path | Purpose | Auth |
| --- | --- | --- | --- |
| POST | `/v1/apps/salesforce/resolve` | Map CRM record to vault + folder | Salesforce session bearer |
| POST | `/v1/apps/salesforce/files` | List files in a CRM record's folder | Salesforce session bearer |
| POST | `/v1/apps/salesforce/upload-context` | Get upload context (vault + folder + VAT) | Salesforce session bearer |
| POST | `/v1/apps/salesforce/unseal` | Unseal vault with VMK/DVAK | Salesforce session bearer |
| POST | `/v1/apps/salesforce/download` | Get Forge URL for file download | Salesforce session bearer |
| POST | `/v1/apps/salesforce/delete-file` | Delete a file from the vault | Salesforce session bearer |
| POST | `/v1/apps/salesforce/oauth/callback` | OAuth install + server-verified vault selection | JWT or API key |
| DELETE | `/v1/apps/salesforce/uninstall` | User-initiated uninstall | JWT or API key |
| POST | `/v1/apps/salesforce/webhooks` | Salesforce webhook events | Salesforce session bearer |

[View full Salesforce documentation →](/api/docs/integrations/salesforce/)

## Common Error Codes

#### Error Responses

| Status | Code | Description |
| --- | --- | --- |
| 400 | `VALIDATION_ERROR` | Invalid or missing required parameters |
| 401 | `AUTHENTICATION_ERROR` | Missing or invalid API key |
| 402 | `PLAN_REQUIRED` | An active subscription is required for this operation |
| 429 | `RATE_LIMIT_EXCEEDED` | Too many requests. Retry after the specified time. |
| 500 | `INTERNAL_ERROR` | Server error. Contact support if persistent. |

## Rate Limits

There are no per-integration rate limits. Rate limiting is **account-wide**: 300 operations per minute in a fixed 60-second window, applied to every authenticated API call. The limiter fails closed: if the rate-limit check itself cannot complete, the request is rejected rather than let through.

Authenticated success responses report your current status in `meta.quota`:

```json
{
  "quota": {
    "limit": 300,
    "used": 15,
    "remaining": 285,
    "resets_at": 1783036860
  }
}
```

Exceeding the limit returns `429 RATE_LIMIT_EXCEEDED` with a `Retry-After` header and `details` carrying `limit`, `used`, and `resets_at`.

> **Need Higher Limits?**
>
> Enterprise customers can request increased rate limits. Contact your account representative or reach out to support@sparkvault.com to discuss your requirements.

## Best Practices

-   **Use scoped API keys**: Create separate keys per application and rotate them regularly.
-   **Handle errors gracefully**: Implement proper error handling and retry logic with exponential backoff for transient failures.
-   **Monitor usage**: Retrieve integration-scoped audit logs with `GET /v1/audit-logs/apps/:app_slug` and Slack usage analytics with `GET /v1/apps/slack/analytics`. Account-wide usage and costs live in the [Reporting API](/api/docs/reporting/).
-   **Cache when appropriate**: Some responses can be cached briefly to reduce API calls, but never cache sensitive data or security-critical values.
-   **Validate inputs client-side**: Reduce API calls by validating parameters before sending requests.
