> ## Documentation Index
> Fetch the complete documentation index at: https://swapnice.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# SDK versus API

> Where the Swapnice SDK and Partner API overlap, and where their capabilities differ.

Both surfaces talk to the same Partner API. The SDK is the supported way to integrate. The REST API is the stable contract underneath it.

The important difference is not "SDK can read profiles and the API cannot." Both can. The SDK adds client-side collection, consent UX, retries, and typed helpers that a raw HTTP integration would otherwise have to build.

## Quick comparison

| Capability                            | TypeScript / Python SDK                 | Raw Partner API                             |
| ------------------------------------- | --------------------------------------- | ------------------------------------------- |
| OAuth 2.1 + PKCE token exchange       | Built in                                | You implement                               |
| Connection session + consent UX       | SDK presents or embeds the connect flow | You host redirects and poll session status  |
| Automatic client-event capture        | Yes, when you register observers        | No. You must construct and POST every event |
| Device and session context enrichment | Added by the runtime SDK                | You must attach `context` yourself          |
| Offline queue and retry               | Yes                                     | You implement                               |
| Idempotency keys                      | Generated and retried for you           | Required header on every mutating call      |
| Typed requests and errors             | Generated from the OpenAPI contract     | You validate payloads                       |
| Server-to-server batch ingest         | SDK `events.batch` helper               | `POST /v1/events/batch`                     |
| Profile, claims, and intent reads     | SDK read methods                        | `GET /v1/profiles/:id` and related routes   |
| Webhook, app, and catalog admin       | Thin SDK wrappers                       | Full HTTP surface                           |
| Consumer app Firebase APIs            | Not available                           | Not available                               |

<Tip>
  If a teammate heard that "the SDK has more functionality," this is what that means: the SDK can observe in-app behavior, run the Swapnice connection and consent flow, and keep events ordered through retries. The API can accept the same events and return the same profiles, but it will not collect or consent for you.
</Tip>

## Use the SDK when

* You are embedding Swapnice in a mobile app, web app, or checkout surface
* You want Swapnice to collect consented first-party events as users move through your product
* You need the hosted connection and consent experience rather than a custom OAuth UI
* You want typed clients, automatic idempotency, and token refresh

Install the generated client:

```bash theme={null}
npm install swapnice-sdk-ts
```

```ts theme={null}
import { SwapniceClient } from "swapnice-sdk-ts";

const swapnice = new SwapniceClient({
  environment: "sandbox",
  clientId: process.env.SWAPNICE_CLIENT_ID!,
  clientSecret: process.env.SWAPNICE_CLIENT_SECRET!,
});
```

The same OpenAPI contract also generates a Python client for backend jobs.

## Use the API directly when

* A partner backend or ETL job is the only writer
* You already collected consent in your own UI and only need to POST receipts and events
* You are registering webhook endpoints, managing apps, or rebuilding ontologies
* You are debugging with cURL, Postman, or an API gateway

Every SDK method maps to a documented HTTP route in the [API reference](/partners/api-overview). Replays and server jobs can call those routes without the client SDK.

## What neither surface does

Neither the SDK nor the Partner API exposes Swapnice consumer-app internals:

* Wallet, Dwolla, or Plaid credentials
* NFC pack activation internals
* Private account fields from the consumer user record
* Another partner's raw events or unresolved identities

Installing the SDK does not expand the purposes a user granted. Events collected for `personalization` stay unavailable for another purpose until that purpose is granted.

## Capability split in practice

```mermaid theme={null}
flowchart LR
    subgraph sdk["SDK runtime"]
        UI["Connect and consent UI"]
        Cap["Event observers"]
        Q["Retry and idempotency queue"]
        Auth["PKCE and token refresh"]
    end

    subgraph api["Partner API"]
        Sess["Connection sessions"]
        Cons["Consent receipts"]
        Ev["Event ingest"]
        Prof["Profiles, claims, intents"]
        Cat["Apps, customers, entries"]
    end

    UI --> Sess
    UI --> Cons
    Cap --> Q
    Auth --> api
    Q --> Ev
    Ev --> Prof
```

The usual split is:

1. **Client SDK** in the consumer-facing app to connect, collect consent, and observe product interactions.
2. **Partner backend + API or server SDK** to upsert customers, register webhooks, and read profiles and intents for the partner product.

See [integration](/partners/integration) for the combined implementation path.
