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

# Connect — embed the consumer Vault

> A hosted consent flow where the consumer approves which scopes you receive — your app never sees their statement or login.

Swippee Connect is the hosted consent flow: the **consumer** signs into their
Swippee Vault, approves which scopes you get, and you receive a `public_token`.
Your app never sees their statement or login.

<Steps>
  <Step title="Your backend creates a request">
    ```bash theme={null}
    curl -X POST https://api.swippee.com/v1/connect/request \
      -H "Authorization: Bearer swippee_sk_live_xxx" \
      -H "Content-Type: application/json" \
      -d '{ "scopes": ["identity","income"], "redirect_uri": "https://yourapp.com/cb" }'

    # → { "request_token": "swln_…", "connect_url": "https://swippee.com/connect?token=swln_…" }
    ```
  </Step>

  <Step title="Open the flow in the browser">
    Script-tag drop-in (any site). The script is first-party — for extra safety
    you can pin it with `integrity` / `crossorigin`.

    ```html theme={null}
    <script src="https://swippee.com/connect.js"></script>
    <script>
      SwippeeConnect.open({
        connectUrl,                       // from step 1 (via your backend)
        onSuccess: ({ public_token }) => exchangeOnYourServer(public_token),
        onExit:    () => {},
      });
    </script>
    ```

    React drop-in (`npm install @swippee/connect-react`):

    ```jsx theme={null}
    import { SwippeeConnect } from "@swippee/connect-react";

    <SwippeeConnect
      createRequest={() => fetch("/api/connect-request").then(r => r.json())}
      onHostedSuccess={({ publicToken }) => exchangeOnYourServer(publicToken)}
    />
    ```
  </Step>

  <Step title="Exchange + read the granted data (server)">
    ```bash theme={null}
    curl -X POST https://api.swippee.com/v1/connect/exchange \
      -H "Authorization: Bearer swippee_sk_live_xxx" \
      -d '{ "public_token": "swln_…" }'
    # → { "access_token": "swac_…", "grant_id": "...", "scopes": [...] }

    # read only the granted views (token in a header, never the URL):
    curl https://api.swippee.com/v1/grants/GRANT_ID/data \
      -H "Authorization: Bearer swippee_sk_live_xxx" \
      -H "X-Swippee-Access-Token: swac_…"
    # → { "granted_scopes": [...], "scopes": [...], "data": { "identity": {...}, "income": {...} } }

    # data minimization: fetch only a subset you need this call with ?include=
    # (returned scopes = granted ∩ requested — never more than granted):
    curl 'https://api.swippee.com/v1/grants/GRANT_ID/data?include=income,verify' \
      -H "Authorization: Bearer swippee_sk_live_xxx" \
      -H "X-Swippee-Access-Token: swac_…"
    ```
  </Step>
</Steps>

<Note>
  The consumer manages and revokes every connection from their Vault; a revoke
  kills the access token immediately.
</Note>

## Audit your consents

For compliance — proving *which customer consents you obtained and how the data
was used* — read your consent + access trail. Both endpoints are **read-only**,
scoped to your organization, and return consent metadata only: **no consumer PII,
no tokens**. (Reading the granted *data* is the separate `GET /v1/grants/:id/data`
above, which additionally requires the access token.)

```bash theme={null}
# List your consent grants (filter with ?status=approved|pending|revoked|expired|denied, ?limit=1..200)
curl 'https://api.swippee.com/v1/grants?status=approved&limit=50' \
  -H "Authorization: Bearer swippee_sk_live_xxx"
# → { "grants": [ {
#     "grant_id": "...", "app_name": "Your app", "consumer_id": "...",
#     "scopes": ["income","verify"], "status": "approved",
#     "created_at": "...", "approved_at": "...", "expires_at": "...",
#     "revoked_at": null, "access_count": 3
#   } ] }

# One grant + its full access audit trail (every read of the granted data)
curl https://api.swippee.com/v1/grants/GRANT_ID \
  -H "Authorization: Bearer swippee_sk_live_xxx"
# → { ...grant fields above..., "access_log": [
#     { "accessed_at": "...", "scope": "all", "ip": "…", "user_agent": "…" }
#   ] }
```

<Note>
  `consumer_id` is an opaque identifier — never the consumer's email, phone, or
  name. The access log records each time *your* app read the granted data.
</Note>
