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

# Quickstart: API Keys

> Use a bearer API key and a subscription to read stock picks free of charge.

Use API keys when your app, backend job, or research pipeline wants a
traditional bearer token instead of wallet-based x402 or MPP payments.

An API key authorizes stock-pick reads with `Authorization: Bearer pk_drip_...`.
With a PRO or EXPERT subscription, in-window reads are **free and uncharged**.
Without a plan, the same route falls through to pay-per-use and spends your
account credits — see [Quickstart: x402 and MPP](/v2/quickstart) for the
wallet-payment path.

<Steps>
  <Step title="Create an API key">
    Sign in to Drip, then create a key from the
    [API keys](https://dripstack.com/connect/api). Copy the key
    when it is shown; raw keys are not displayed again.

    Add or start a subscription from the
    [Billing](https://dripstack.com/billing).
  </Step>

  <Step title="Preview the day for free">
    The quote route needs no auth. Use it to see whether a day has picks before
    you request it.

    ```bash theme={null}
    curl "https://dripstack.com/api/v2/stock-picks/quote?date=2026-05-30&limit=200"
    ```

    ```json theme={null}
    {
      "dateUsed": "2026-05-30",
      "startDate": "2026-05-30",
      "endDate": "2026-05-30",
      "asOf": "2026-05-31T00:05:12.000Z",
      "count": 184,
      "attributedPostCount": 37,
      "amountUsd": "1.85",
      "posts": [
        { "publicationSlug": "example-finance-newsletter.com", "amountUsd": "0.05" }
      ]
    }
    ```
  </Step>

  <Step title="Read the picks">
    One UTC day, with your key. PRO readers get the live 7-day window, EXPERT
    readers get full history.

    ```bash theme={null}
    export DRIP_API_KEY="pk_drip_YOUR_KEY"

    curl -s \
      "https://dripstack.com/api/v2/stock-picks?date=2026-05-30&limit=200" \
      -H "Authorization: Bearer $DRIP_API_KEY"
    ```
  </Step>

  <Step title="Page back through a range">
    EXPERT plan. `limitDays` bounds each page and `cursor` continues older.
    Always pass the previous response's `pagination.nextCursor` unchanged.

    ```bash theme={null}
    curl -s \
      "https://dripstack.com/api/v2/stock-picks?from=2026-05-01&to=2026-05-31&sort=oldest&limitDays=3" \
      -H "Authorization: Bearer $DRIP_API_KEY"
    ```
  </Step>
</Steps>

## Request examples

<Tabs>
  <Tab title="cURL">
    ```bash theme={null}
    export DRIP_API_KEY="pk_drip_YOUR_KEY"

    curl -s \
      "https://dripstack.com/api/v2/stock-picks?date=2026-05-30&limit=200" \
      -H "Authorization: Bearer $DRIP_API_KEY"
    ```
  </Tab>

  <Tab title="JavaScript">
    ```typescript theme={null}
    const baseUrl = "https://dripstack.com";

    const response = await fetch(
      `${baseUrl}/api/v2/stock-picks?date=2026-05-30&limit=200`,
      { headers: { Authorization: `Bearer ${process.env.DRIP_API_KEY}` } },
    );

    if (response.status === 403) {
      const body = await response.json();
      throw new Error(
        `Out of plan window. Allowed: ${JSON.stringify(body.meta?.allowedRange)}`,
      );
    }

    if (!response.ok) {
      throw new Error(`Drip request failed: ${response.status}`);
    }

    const { meta, picks } = await response.json();
    console.log(meta.appliedRange, picks.length);
    for (const pick of picks) {
      // Historical subscriber reads carry prices; the current day does not.
      const move = pick.prices ? `${pick.prices.returnPct}%` : "no price yet";
      console.log(
        pick.date,
        pick.ticker,
        pick.action,
        `conviction ${pick.conviction}`,
        pick.author,
        move,
      );
      console.log(`  "${pick.evidenceQuote}"`);
    }
    ```
  </Tab>

  <Tab title="Python">
    ```bash theme={null}
    pip install requests
    ```

    ```python theme={null}
    import os

    import requests

    response = requests.get(
        "https://dripstack.com/api/v2/stock-picks?date=2026-05-30&limit=200",
        headers={"Authorization": f"Bearer {os.environ['DRIP_API_KEY']}"},
        timeout=30,
    )

    response.raise_for_status()

    data = response.json()
    print(data["meta"]["plan"], data["meta"]["appliedRange"])
    for pick in data["picks"]:
        move = pick.get("prices", {}).get("returnPct")
        move_text = f"{move}%" if move is not None else "no price yet"
        print(pick["date"], pick["ticker"], pick["action"], pick["author"], move_text)
        print(f'  "{pick["evidenceQuote"]}"')
    ```
  </Tab>
</Tabs>

## More picks in one call

Pass a range instead of a day. `limitDays` (1-30) sets how many days come back
per page and `limit` sets rows per day, so `limitDays=30&limit=500` returns a
month of picks in one request.

```bash theme={null}
curl -s \
  "https://dripstack.com/api/v2/stock-picks?from=2026-05-01&to=2026-05-30&limitDays=30&limit=500&sort=oldest" \
  -H "Authorization: Bearer $DRIP_API_KEY"
```

When more days remain, `pagination.nextCursor` holds the oldest day returned —
pass it as `cursor` to continue older. Historical subscription reads include
`prices` (`entry`, `current`, direction-adjusted `returnPct`, `currency`).

## Example response

A day in the life of the feed: several sources calling the same names, one with
prices attached, one without an attributed post.

```json theme={null}
{
  "meta": {
    "plan": "PRO",
    "asOf": "2026-05-31T00:05:12.000Z",
    "requestAllowance": 50000,
    "appliedRange": { "from": "2026-05-30", "to": "2026-05-30" },
    "allowedRange": { "from": "2026-05-24", "to": "2026-05-31" }
  },
  "pagination": { "count": 5, "nextCursor": null },
  "picks": [
    {
      "date": "2026-05-30",
      "ticker": "NVDA",
      "tickerExchange": "NASDAQ",
      "instrumentType": "EQUITY",
      "assetId": "asset_9f2c1d",
      "assetResolutionStatus": "RESOLVED",
      "asset": {
        "id": "asset_9f2c1d",
        "name": "NVIDIA Corporation",
        "kind": "EQUITY",
        "symbol": "NVDA",
        "exchangeMic": "XNAS",
        "currency": "USD"
      },
      "action": "ADD",
      "author": "Example Analyst",
      "publicationSlug": "example-finance-newsletter.com",
      "publicationTitle": "Example Finance Newsletter",
      "articleUrl": "https://dripstack.com/api/v1/publications/example-finance-newsletter.com/nvda-position-review",
      "conviction": 4,
      "convictionLabel": "high",
      "evidenceQuote": "Adding to my NVDA position on the pullback — datacenter revenue is still running ahead of consensus.",
      "thesis": "The author adds to an existing long after a ~12% drawdown, arguing forward AI capex guidance from hyperscalers supports another leg up.",
      "sentiment": "BULLISH",
      "rationaleSnippet": "Add to existing long; AI capex estimates still rising while the stock de-rated.",
      "publishedAt": "2026-05-30T11:24:07.000Z",
      "prices": { "entry": 121.44, "current": 128.9, "returnPct": 6.15, "currency": "USD" }
    },
    {
      "date": "2026-05-30",
      "ticker": "NVDA",
      "tickerExchange": "NASDAQ",
      "instrumentType": "EQUITY",
      "assetId": "asset_9f2c1d",
      "assetResolutionStatus": "RESOLVED",
      "asset": {
        "id": "asset_9f2c1d",
        "name": "NVIDIA Corporation",
        "kind": "EQUITY",
        "symbol": "NVDA",
        "exchangeMic": "XNAS",
        "currency": "USD"
      },
      "action": "REDUCE",
      "author": "Another Writer",
      "publicationSlug": "second-publication.com",
      "publicationTitle": "Second Publication",
      "articleUrl": "https://dripstack.com/api/v1/publications/second-publication.com/nvda-trim",
      "conviction": 2,
      "convictionLabel": "low",
      "evidenceQuote": "Trimming NVDA by a third — the position has done its work and I want to fund the power-grid name.",
      "thesis": null,
      "sentiment": "BEARISH",
      "rationaleSnippet": "Trim a winner to fund another position.",
      "publishedAt": "2026-05-30T10:05:41.000Z",
      "prices": { "entry": 121.44, "current": 128.9, "returnPct": -6.15, "currency": "USD" }
    },
    {
      "date": "2026-05-30",
      "ticker": "SMCI",
      "tickerExchange": "NASDAQ",
      "instrumentType": "EQUITY",
      "assetId": null,
      "assetResolutionStatus": "PENDING",
      "asset": null,
      "action": "NEW_POSITION",
      "author": "Third Writer",
      "publicationSlug": "second-publication.com",
      "publicationTitle": "Second Publication",
      "articleUrl": "https://dripstack.com/api/v1/publications/second-publication.com/smci-new-position",
      "conviction": 2,
      "convictionLabel": "low",
      "evidenceQuote": "Opening a small SMCI position here; rack margins are inflecting and the backlog is not priced in.",
      "thesis": null,
      "sentiment": "BULLISH",
      "rationaleSnippet": null,
      "publishedAt": "2026-05-30T09:02:55.000Z"
    },
    {
      "date": "2026-05-30",
      "ticker": "BTC-USD",
      "tickerExchange": null,
      "instrumentType": "CRYPTO",
      "assetId": "asset_7b41ee",
      "assetResolutionStatus": "RESOLVED",
      "asset": {
        "id": "asset_7b41ee",
        "name": "Bitcoin",
        "kind": "CRYPTO",
        "symbol": "BTC-USD",
        "exchangeMic": null,
        "currency": "USD"
      },
      "action": "OPINION",
      "author": "Third Writer",
      "publicationSlug": null,
      "publicationTitle": null,
      "articleUrl": "https://third-writer.substack.com/p/btc-position-review",
      "conviction": 3,
      "convictionLabel": "medium",
      "evidenceQuote": "Still structurally bullish bitcoin, but I would not add above this level until the ETF flows turn.",
      "thesis": "The author expresses a directional view without framing it as a trade, so no entry or exit is extracted.",
      "sentiment": "BULLISH",
      "rationaleSnippet": "Structural bullishness; waiting on ETF flows before adding.",
      "publishedAt": "2026-05-30T13:41:20.000Z",
      "prices": { "entry": 96250.0, "current": 94880.5, "returnPct": -1.42, "currency": "USD" }
    },
    {
      "date": "2026-05-30",
      "ticker": "TLT",
      "tickerExchange": "NASDAQ",
      "instrumentType": "ETF",
      "assetId": "asset_5c30ab",
      "assetResolutionStatus": "UNRESOLVED",
      "asset": null,
      "action": "HOLD",
      "author": "Example Analyst",
      "publicationSlug": "example-finance-newsletter.com",
      "publicationTitle": "Example Finance Newsletter",
      "articleUrl": "https://dripstack.com/api/v1/publications/example-finance-newsletter.com/long-bonds-weekly",
      "conviction": 1,
      "convictionLabel": "low",
      "evidenceQuote": "Holding the long-bond position; nothing in the inflation print changes the rate path.",
      "thesis": null,
      "sentiment": "NEUTRAL",
      "rationaleSnippet": null,
      "publishedAt": "2026-05-30T08:15:02.000Z"
    }
  ]
}
```

A successful query can return `picks: []` — an empty day is not an error.
`asset` and `assetId` are null until the ticker is resolved; use
[`asset.kind`](/v2/stock-picks#pick-fields) for identity, and
[Company Lookup](/v2/companies) when you need to resolve one yourself.

## Common responses

| Status | Meaning | Action |
| - | - | - |
| `200` | Picks returned, no charge on a subscription plan | Read `picks[]` |
| `401` | Invalid API key | Check the bearer token |
| `402` | Payment required (no plan, no credits) | Use the quote → pay flow |
| `403` | Date outside the plan window, or no credits | Read `meta.allowedRange`, or top up |
| `404` | No picks on the paid path for that day | Do not pay |
| `429` | Monthly request allowance exhausted | Wait for the allowance to reset |

<Warning>
  Keep API keys server-side. Do not ship `pk_drip_...` keys in browser code, public repositories, or
  agent traces.
</Warning>


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.