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

# Provider Onboarding

> Step-by-step signup walkthrough — from wallet connect to first paid query.

# Provider Onboarding

This guide walks you through registering as a ShadowFeed data provider.

**Estimated time:** 5 minutes for sign-up, 30 minutes to wire up your HMAC verifier (Partner Bridge mode only).

## Prerequisites

* A Stacks wallet installed: [Leather](https://leather.io/) or [Xverse](https://www.xverse.app/)
* For **Partner Bridge** mode: an HTTPS endpoint you control (e.g. `https://api.yourcompany.com`)
* For **Hosted Mirror** mode: a public JSON URL or willingness to push data via webhook

## Step 1 — Sign in with your Stacks wallet

<Steps>
  <Step title="Visit shadowfeed.app">
    Open [shadowfeed.app](https://shadowfeed.app) in a browser with Leather or Xverse extension installed.
  </Step>

  <Step title="Connect wallet">
    Click **Connect Wallet** → choose Leather or Xverse → approve in the popup.
  </Step>

  <Step title="Sign-In With Stacks">
    Click **Providers** in the nav → **Become a Provider**. Sign the SIWS challenge — this proves wallet ownership without exposing your private key.
  </Step>
</Steps>

<Note>
  Your wallet address becomes your provider account identity. You can link a *different* wallet for withdrawals later if revenue should go elsewhere (multisig, treasury, etc.).
</Note>

## Step 2 — Profile (wizard step 1)

| Field            | Required | Notes                                                                             |
| ---------------- | -------- | --------------------------------------------------------------------------------- |
| **Handle**       | Yes      | URL slug, 3-32 chars, lowercase + numbers + hyphens. Becomes `/providers/handle`. |
| **Display name** | Yes      | Shown on your profile + agent UI                                                  |
| **Description**  | No       | One-sentence pitch                                                                |
| **Website**      | No       | Linked from profile                                                               |
| **X (Twitter)**  | No       | `@handle` for community attribution                                               |

<Warning>
  Reserved handles (`admin`, `api`, `auth`, `dashboard`, `system`, etc.) are blocked. Pick a handle specific to your brand.
</Warning>

## Step 3 — Integration mode (wizard step 2)

<Tabs>
  <Tab title="Partner Bridge">
    Pick this if you already have a production API — including one you already gate with x402 on Solana, Base, or another EVM chain. You point ShadowFeed at the same endpoint; it bypasses your existing paywall with an HMAC signature (see [Coexisting with your existing x402 paywall](/providers/hmac-integration#coexisting-with-your-existing-x402-paywall)).

    **Required:** partner endpoint URL — an **origin only**, e.g. `https://api.yourcompany.com`. No path, no trailing slash. The per-feed `source_path` (next step) is appended to this. Registering a path here (e.g. `…/v1`) is the most common cause of dead-on-arrival integrations.

    The wizard will generate an HMAC secret in step 4. **Save it immediately** — it's shown once.
  </Tab>

  <Tab title="Hosted Mirror">
    Pick this if you have data but no API server.

    No fields required in this step. You'll configure data sources per-feed in the next step.
  </Tab>
</Tabs>

## Step 4 — Add your first feed (wizard step 3)

| Field             | Required              | Notes                                                                                                                                                                                                                                                                  |
| ----------------- | --------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **Feed slug**     | Yes                   | Unique per provider, e.g. `whales`, `gas-prices`                                                                                                                                                                                                                       |
| **Display name**  | Yes                   | E.g. "Whale Alerts"                                                                                                                                                                                                                                                    |
| **Description**   | No                    | Helps agents discover your feed                                                                                                                                                                                                                                        |
| **Price (STX)**   | Yes                   | Per-query cost. Suggested: 0.003 - 0.05 STX                                                                                                                                                                                                                            |
| **Source path**   | Partner Bridge        | The **exact** route your server already serves, starting with `/` — e.g. `/whale-alerts`. ShadowFeed calls `partner_endpoint + source_path` and signs this path verbatim, so it must match a real route and must not repeat any segment already in `partner_endpoint`. |
| **Source type**   | Hosted Mirror         | `github_raw`, `r2_url`, `webhook_push`, `manual_upload`                                                                                                                                                                                                                |
| **Source URL**    | Hosted Mirror polling | HTTPS URL to fetch JSON from                                                                                                                                                                                                                                           |
| **Poll interval** | Hosted Mirror polling | 60s, 5min, 15min, or 1 hour                                                                                                                                                                                                                                            |

After submit, your provider goes from `pending` to `active` and the feed is live at `/feeds/p/your-handle/feed-slug`.

## Step 5 — Save your HMAC secret

This step only applies to **Partner Bridge** mode.

The wizard's success screen shows the secret **once**. It looks like:

```text theme={null}
Z0rczxIVJuearIMIyAEy6solyqx2gCb4MKBhGqxcNEQ
```

You'll see an integration guide right under the secret with copy-pasteable middleware code in three languages.

<Warning>
  Copy the secret immediately. We only store a hash, so we cannot recover the plaintext if you lose it. If lost, rotate from the dashboard — but the old secret stops working instantly.
</Warning>

## Step 6 — Where to put the HMAC secret

This is the most common point of confusion: **on which server does the secret live?**

**Answer: on the same server that hosts your `partner_endpoint`.** Whatever domain/runtime serves the URL ShadowFeed will call.

| Your `partner_endpoint` runtime | How to set the secret                                          |
| ------------------------------- | -------------------------------------------------------------- |
| Cloudflare Workers              | `wrangler secret put SHADOWFEED_PARTNER_SECRET`                |
| Vercel                          | Dashboard → Settings → Environment Variables                   |
| Railway / Fly.io                | Project → Variables → Add                                      |
| Render                          | Service → Environment → Add Environment Variable               |
| AWS Lambda                      | Console → Configuration → Environment variables                |
| Docker / VPS                    | `.env` file loaded by your process, or systemd EnvironmentFile |
| Heroku                          | `heroku config:set SHADOWFEED_PARTNER_SECRET=...`              |

<Note>
  The secret **never gets put on ShadowFeed's side as a user-facing config**. We already store it as a hash for verification at signup time. You only manage it on **your** side.
</Note>

After setting the env var, your code reads it via the standard mechanism:

<Tabs>
  <Tab title="TypeScript / Node">
    ```typescript theme={null}
    const secret = process.env.SHADOWFEED_PARTNER_SECRET;
    ```
  </Tab>

  <Tab title="Cloudflare Workers">
    ```typescript theme={null}
    const secret = c.env.SHADOWFEED_PARTNER_SECRET;
    ```
  </Tab>

  <Tab title="Python">
    ```python theme={null}
    secret = os.environ["SHADOWFEED_PARTNER_SECRET"]
    ```
  </Tab>

  <Tab title="Go">
    ```go theme={null}
    secret := os.Getenv("SHADOWFEED_PARTNER_SECRET")
    ```
  </Tab>
</Tabs>

Continue to the [HMAC Integration Guide](/providers/hmac-integration) for the full verifier middleware.

## Step 7 — Link a withdrawal wallet

Before you can withdraw STX, you must link a destination wallet. This can be the same wallet you signed in with, or a different one (multisig, treasury).

<Steps>
  <Step title="Open the warning banner">
    In the dashboard, click **link one** under the "⚠ No linked withdrawal wallet" message.
  </Step>

  <Step title="Sign the linking challenge">
    The destination wallet signs a SIWS message proving ownership.
  </Step>

  <Step title="Verify">
    The dashboard now shows "Linked withdrawal: SP..."
  </Step>
</Steps>

Withdrawals can only go to this linked address. To change it later, sign a new linking challenge with the new wallet.

## Step 8 — Verify end-to-end

**First, run the free handshake test — before spending any STX.** In the dashboard click **Test connection** (`POST /providers/id/:id/hmac/test`), or `npx shadowfeed verify --endpoint https://api.you.com --secret "$SHADOWFEED_PARTNER_SECRET"` if you use the SDK. It signs a request with your stored secret against your first feed's `source_path` and probes your endpoint exactly like a real buyer would — catching secret and path mismatches in seconds. Don't activate until this returns `ok`. Full breakdown: [HMAC Integration → Verify your wiring](/providers/hmac-integration#verify-your-wiring-before-going-live).

Then confirm the unpaid path returns a 402 challenge:

```bash theme={null}
# Without payment — should return 402 with payment requirements
curl -i https://api.shadowfeed.app/feeds/p/your-handle/feed-slug
```

Finally, run one real pay-per-call test with the [ShadowFeed Agent SDK](/sdk/installation):

```typescript theme={null}
import { ShadowFeed } from 'shadowfeed-agent';

const sf = new ShadowFeed({
  privateKey: process.env.AGENT_PRIVATE_KEY,
  network: 'mainnet',
});

const result = await sf.buy('p/your-handle/feed-slug');
console.log(result.data);
```

When the agent pays:

<Steps>
  <Step title="STX settles on platform">
    Agent's STX transaction lands on the ShadowFeed platform wallet.
  </Step>

  <Step title="ShadowFeed forwards HMAC-signed request">
    Calls `partner_endpoint + source_path` with X-Sf-\* headers.
  </Step>

  <Step title="Your middleware verifies + serves">
    Middleware validates signature, your route returns data.
  </Step>

  <Step title="Revenue credited">
    97% of the price lands in your `pending_revenue` counter.
  </Step>

  <Step title="Dashboard updates">
    Query log entry appears with TX hash linkable to Hiro Explorer.
  </Step>
</Steps>

## Step 9 — Publish your discovery manifest

Publish a `.well-known/shadowfeed-feeds.json` file **on your own domain**. This is how marketplaces, partners, and grant reviewers independently confirm — from infrastructure *you* control — that you opted into ShadowFeed. ShadowFeed's public verification endpoint (`/providers/your-handle/manifest`) fetches this file live and reports it under `independence_attestation.well_known_manifest_present`.

<Note>
  Using `@shadowfeed/provider-sdk`? This file is generated and served for you automatically from your registered feeds — skip straight to the verification commands below. The manual work here only applies to hand-rolled Partner Bridge integrations.
</Note>

Serve it at the root of the **same website domain** you registered in Step 2:

```
https://yourdomain.com/.well-known/shadowfeed-feeds.json
```

<Warning>
  It must resolve at the exact domain you registered — watch apex-vs-`www` redirects. If `yourdomain.com` 307-redirects to `www.yourdomain.com` and the file only lives on one of them, the check returns `well_known_manifest_present: false`. Always test the registered URL while following redirects: `curl -IL https://yourdomain.com/.well-known/shadowfeed-feeds.json`.
</Warning>

Use this shape — the live [Hyre manifest](https://hyreagent.fun/.well-known/shadowfeed-feeds.json) is the reference implementation:

```json theme={null}
{
  "version": "1",
  "provider": {
    "name": "Your Company",
    "handle": "your-handle",
    "description": "One-sentence pitch.",
    "website": "https://yourdomain.com",
    "api": "https://api.yourdomain.com",
    "twitter_handle": "@your_handle",
    "contact_email": "you@yourdomain.com"
  },
  "partnerships": [
    {
      "marketplace": "shadowfeed",
      "marketplace_url": "https://shadowfeed.app",
      "marketplace_handle": "your-handle",
      "marketplace_verification_url": "https://api.shadowfeed.app/providers/your-handle/manifest",
      "integration_mode": "partner_bridge",
      "partner_endpoint": "https://api.yourdomain.com"
    }
  ],
  "feeds": [
    { "slug": "signal", "name": "Crypto Signal", "category": "signals", "path": "/signal", "method": "GET", "suggested_price_stx": 0.005 }
  ],
  "supported_payments": [
    { "scheme": "partner_bridge", "marketplace": "shadowfeed", "asset": "STX", "settlement_network": "stacks:mainnet" }
  ]
}
```

Each `feeds[].path` must match the `source_path` you registered in Step 4. If you cross-list on other marketplaces (x402scan, payai, etc.), add one entry per marketplace under `partnerships` so every partner can verify you from this single file.

**Verify it's detected:**

```bash theme={null}
# Your file resolves at the registered domain (follow redirects)
curl -IL https://yourdomain.com/.well-known/shadowfeed-feeds.json    # expect: HTTP 200

# ShadowFeed sees it
curl -s https://api.shadowfeed.app/providers/your-handle/manifest \
  | grep well_known_manifest_present                                  # expect: true
```

## What's next

<CardGroup cols={2}>
  <Card title="HMAC Integration Guide" icon="code" href="/providers/hmac-integration">
    Verifier code in TypeScript, Python, and Go — copy-paste ready.
  </Card>

  <Card title="Withdrawals & Revenue" icon="wallet" href="/providers/withdrawals">
    Sign a withdrawal, link a wallet, view settlement history.
  </Card>

  <Card title="Troubleshooting" icon="circle-question" href="/providers/troubleshooting">
    Common errors and how to fix them.
  </Card>

  <Card title="Provider dashboard" icon="grid" href="https://shadowfeed.app/#/providers">
    Live portal for managing feeds and revenue.
  </Card>
</CardGroup>
