npm package: @flowcheck/sdk
Description: TypeScript SDK for the FlowCheck API — Stripe payouts, Shopify orders, and bank data in one API
Author: FlowCheck
Latest version: 0.2.2

# @flowcheck/sdk

TypeScript SDK for the [FlowCheck API](https://developer.usepopup.com) — unified access to Stripe payouts, Shopify orders, and bank transaction data.

## Install

```bash
npm install @flowcheck/sdk
```

## Quick start

```typescript
import { FlowCheck } from "@flowcheck/sdk";

const fc = new FlowCheck("fc_live_...");

// Get cash flow for the last 30 days
const { data } = await fc.cashflow("30d");
console.log(`Net: $${data.net / 100}`);

// List Shopify payouts only
const shopify = await fc.payouts({ source: "shopify" });
console.log(`${shopify.data.length} Shopify payouts`);

// Check for unmatched payouts
const summary = await fc.reconciliationSummary();
console.log(summary.data.summary);
```

### curl equivalent

```bash
curl https://developer.usepopup.com/api/v0/cashflow?window=30d \
  -H "Authorization: Bearer fc_live_..."
```

### Example response

```json
{
  "data": {
    "window": "30d",
    "total_inflow": 523400,
    "total_outflow": 187600,
    "net": 335800,
    "daily": [
      { "date": "2026-03-05", "inflow": 18200, "outflow": 4300, "net": 13900 },
      { "date": "2026-03-04", "inflow": 22100, "outflow": 6800, "net": 15300 }
    ]
  },
  "meta": {
    "request_id": "req_abc123",
    "timestamp": "2026-03-05T10:00:00Z",
    "version": "v0"
  },
  "errors": []
}
```

All amounts are in **cents** (USD).

## Methods

### Auth

| Method | HTTP | Description |
|--------|------|-------------|
| `register(email)` | `POST /auth/register` | Create account (no key needed) |
| `registrationStatus(token)` | `GET /auth/register/status` | Check registration / get API key |

### Financial Data

| Method | HTTP | Description |
|--------|------|-------------|
| `balance()` | `GET /balance` | Stripe + bank balances |
| `cashflow(window?)` | `GET /cashflow` | Revenue, expenses, net by day |
| `payouts(params?)` | `GET /payouts` | Stripe + Shopify payouts with match status |
| `payout(id)` | `GET /payouts/:id` | Single payout with bank match |
| `transactions(params?)` | `GET /transactions` | Bank transactions from Plaid |
| `discrepancies(params?)` | `GET /discrepancies` | Missing or mismatched amounts |
| `reconciliationSummary()` | `GET /reconcile/summary` | 30-day reconciliation summary |
| `reconciliation(payoutId)` | `GET /reconcile/:id` | Per-payout reconciliation detail |

### Agent

| Method | HTTP | Description |
|--------|------|-------------|
| `agentPosition()` | `GET /agent/position` | Full financial snapshot for AI agents |
| `agentAlerts()` | `GET /agent/alerts` | Active issues for AI agents |

### Integrations

| Method | HTTP | Description |
|--------|------|-------------|
| `connectStripe(restrictedKey)` | `POST /connect/stripe` | Connect Stripe account |
| `connectShopify(shop, accessToken)` | `POST /connect/shopify` | Connect Shopify store |
| `createPlaidLinkToken()` | `POST /connect/plaid/link-token` | Start Plaid bank connection |
| `exchangePlaidToken(publicToken)` | `POST /connect/plaid/exchange` | Complete Plaid connection |

### Webhooks

| Method | HTTP | Description |
|--------|------|-------------|
| `webhooks()` | `GET /webhooks` | List webhook endpoints |
| `createWebhook(url, events)` | `POST /webhooks` | Register webhook endpoint |
| `deleteWebhook(id)` | `DELETE /webhooks/:id` | Remove webhook endpoint |

### Billing

| Method | HTTP | Description |
|--------|------|-------------|
| `upgradePlan(plan)` | `POST /billing/upgrade` | Get checkout URL to upgrade (works at 0 credits) |
| `topUp()` | `POST /billing/topup` | Buy 100 credits for $5 |

## Filtering payouts by source

```typescript
// All payouts
const all = await fc.payouts();

// Stripe only
const stripe = await fc.payouts({ source: "stripe" });

// Shopify only
const shopify = await fc.payouts({ source: "shopify" });
```

## Pagination

List endpoints (`payouts`, `transactions`, `discrepancies`) support cursor-based pagination:

```typescript
const first = await fc.payouts({ limit: 10 });
console.log(first.data); // first 10 payouts

if (first.meta.has_more) {
  const next = await fc.payouts({ limit: 10, cursor: first.meta.cursor });
  console.log(next.data); // next 10 payouts
}
```

## Error handling

The SDK throws on non-2xx responses. The error includes `status` and `body`:

```typescript
try {
  await fc.balance();
} catch (err) {
  if (err.status === 401) {
    console.log("Invalid API key");
  }
  if (err.status === 402) {
    console.log("Out of credits — upgrade or top up");
    // Programmatic upgrade:
    const { data } = await fc.upgradePlan("starter");
    console.log(`Upgrade at: ${data.checkout_url}`);
  }
  console.log(err.body); // full error response
}
```

## Get an API key

Sign up at [developer.usepopup.com](https://developer.usepopup.com) to get your API key. 7-day free trial with 100 credits included.

## Links

- [API Documentation](https://developer.usepopup.com/docs)
- [OpenAPI Spec](https://developer.usepopup.com/.well-known/openapi.json)
- [MCP Server](https://www.npmjs.com/package/@flowcheck/mcp-server)
- [llms.txt](https://developer.usepopup.com/llms.txt)

## License

MIT