Fund My Squad
Partner API Documentation

Partner API Documentation

Everything you need to integrate Fund My Squad fundraising into your platform. Machine-readable version available at /llms.txt

Implementation Overview

Fund My Squad (FMS) is a fundraising platform for youth sports. The Partner API lets external platforms (league management, team apps, registration software) offer built-in fundraising to their users. Partners earn commission on every donation processed through fundraisers created via their integration.

Integration Flow:

┌─────────────────────────────────────────────────────────────────┐
│                     PARTNER INTEGRATION FLOW                     │
└─────────────────────────────────────────────────────────────────┘

1. SETUP Apply at /partners → Get staging API key → Build & test in sandbox

2. CREATE FUNDRAISER (your platform → FMS API) Your user wants to fundraise → POST /partner/v1/fundraisers {title, goalAmount, externalId} → FMS returns id, publicUrl, donateUrl

3. COLLECT DONATIONS (donors → FMS hosted page) Share the donateUrl or embed link → Donor visits FMS donation page → FMS processes payment via Stripe

4. ENABLE PAYOUTS (fundraiser creator → Stripe Connect) POST /partner/v1/fundraisers/:id/connect/onboard → Redirect user to Stripe onboarding → User completes KYC/banking setup

5. TRACK & DISPLAY (FMS API → your platform) GET /partner/v1/fundraisers/:id → Show progress GET /partner/v1/fundraisers/:id/donations → Show donors

6. COMMISSION PAYOUT (automatic on each donation) Donor pays $100 → Stripe fee ~$3.20 → Platform fee (10%): $10.00 → Partner commission (e.g. 4%): $4.00 → FMS keeps: $6.00 → Fundraiser creator receives: $86.80

Quick Start: 1. Apply at https://fundmysquad.com/partners 2. Once approved, log in to the Partner Portal 3. Generate a staging API key from the API Keys tab 4. Test all endpoints in the Sandbox tab 5. Request a production API key 6. Integrate into your platform and go live

Full machine-readable docs: https://fundmysquad.com/llms.txt

Authentication

All API requests require your partner API key in the x-partner-api-key header:

curl https://api.fundmysquad.com/partner/v1/fundraisers \
  -H "x-partner-api-key: fms_partner_abc123..."

Base URL: Always use https://api.fundmysquad.com for all requests.

Environments:

Key TypeBehavior
Staging keysRequests are automatically routed to the sandbox environment. No real data is created. Response includes x-fms-environment: sandbox header.
Production keysRequests hit the production environment. Real fundraisers, real donations.

Partners always use the same base URL. The API detects whether your key is staging or production and routes accordingly. Staging key requests never touch the production database.

Create a Fundraiser

POST /partner/v1/fundraisers

Required fields:

  • title (string) — Fundraiser title
  • goalAmount (number) — Goal in dollars (e.g. 5000)
  • externalId (string) — Your platform's unique ID for the team/user

    Optional fields:

  • description (string), goalType ("team" or "individual"), category, sport
  • heroImageUrl (string), startsAt, endsAt (ISO 8601)
  • metadata (object) — Arbitrary JSON for your own tracking
  • connectExternalOwnerId (string) — attach a reusable owner Connect account (see Stripe Connect)

    Example:

  • curl -X POST https://api.fundmysquad.com/partner/v1/fundraisers \
      -H "x-partner-api-key: fms_partner_abc123..." \
      -H "Content-Type: application/json" \
      -d '{
        "title": "Tigers Spring Travel Fund",
        "goalAmount": 5000,
        "goalType": "team",
        "externalId": "team_8472",
        "sport": "baseball",
        "endsAt": "2026-06-01T00:00:00Z"
      }'
    

    Returns the created fundraiser with its id, publicUrl, and donateUrl.

    List Fundraisers

    GET /partner/v1/fundraisers
    

    Query parameters:

  • externalId — Filter by your team/user ID
  • status — Filter: active, closed, draft
  • sortnewest, oldest, most_raised, ending_soon
  • limit (max 100), offset — Pagination

    Example:

  • curl "https://api.fundmysquad.com/partner/v1/fundraisers?externalId=team_8472&status=active" \
      -H "x-partner-api-key: fms_partner_abc123..."
    

    Get Fundraiser Details

    GET /partner/v1/fundraisers/:id
    

    Returns full details including current stats (raised amount, donation count, supporter count, progress %) and the 10 most recent donations.

    Lookup by external ID:

    GET /partner/v1/fundraisers/by-external-id/:externalId
    

    Update a Fundraiser

    PATCH /partner/v1/fundraisers/:id
    

    Updatable fields: title, description, goalAmount, startsAt, endsAt, category, sport, heroImageUrl, externalId, metadata

    Only include the fields you want to change. Omitted fields are left unchanged.

    curl -X PATCH https://api.fundmysquad.com/partner/v1/fundraisers/abc123... \
      -H "x-partner-api-key: fms_partner_abc123..." \
      -H "Content-Type: application/json" \
      -d '{ "goalAmount": 7500 }'
    

    Close & Reopen

    Close a fundraiser:

    POST /partner/v1/fundraisers/:id/close
    

    Reopen a closed fundraiser:

    POST /partner/v1/fundraisers/:id/reopen
    
    Optionally pass { "endsAt": "2026-08-01T00:00:00Z" } to set a new end date.

    Donations & Stats

    List donations:

    GET /partner/v1/fundraisers/:id/donations?limit=50&offset=0
    

    Fundraiser stats (with 14-day trend):

    GET /partner/v1/fundraisers/:id/stats
    

    Portfolio summary:

    GET /partner/v1/summary
    
    Returns aggregate stats across all your fundraisers: total raised, active/closed counts, unique teams, total donors.

    Stripe Connect (Payouts)

    Onboard a fundraiser creator for payouts:

    POST /partner/v1/fundraisers/:id/connect/onboard
    

    Required fields:

  • returnUrl (string) — Where to redirect after Stripe onboarding

    Optional fields:

  • refreshUrl (string) — Where to redirect if the link expires

    Response:

  • {
      "onboardingUrl": "https://connect.stripe.com/...",
      "stripeAccountId": "acct_...",
      "message": "Redirect the fundraiser creator to onboardingUrl..."
    }
    

    Redirect your user to onboardingUrl. After completing Stripe's KYC/banking setup, they'll be redirected to your returnUrl.

    Check Connect status:

    GET /partner/v1/fundraisers/:id/connect/status
    

    Returns connected (boolean), chargesEnabled, payoutsEnabled, detailsSubmitted.

    Commission splits: When a donation is made to a partner-created fundraiser with a connected payout account:

  • Fundraiser creator: donation minus platform fee and Stripe fees
  • Partner: commission (set by FMS admin) — comes out of platform fee
  • FMS: remaining platform fee

    ---

    Reusable owner Connect accounts

    Onboard a payout account once per owner (a team, club, or individual on your platform) and reuse it across many fundraisers — instead of onboarding per fundraiser. Keyed by your externalOwnerId.

    POST /partner/v1/connect/onboard
  • Body: { externalOwnerId, ownerType: "entity" | "individual", email?, returnUrl, refreshUrl? }. Find-or-creates the owner's Connect account and returns { onboardingUrl, connectAccountId }, or { status: "already_connected", connectAccountId } if already done.

    GET /partner/v1/connect/status?externalOwnerId=...
    
    Returns connected, status, chargesEnabled, payoutsEnabled, detailsSubmitted, connectAccountId.

    Attach to a fundraiser — either pass connectExternalOwnerId when creating the fundraiser, or link an existing fundraiser:

    POST /partner/v1/fundraisers/:id/connect/link
    
    Body: { externalOwnerId }. Sets the fundraiser's payout account to that owner's Connect account.

    The per-fundraiser /connect/onboard flow above still works for one-off fundraisers.

    Product Fundraisers

    Sell products (candy, cookie dough, merch) instead of — or alongside — donations.

    Turn on the shop: set shopEnabled: true when creating a fundraiser (or PATCH it on later), plus optional shopHeadline and shopDescription. Adding the first product also enables the shop automatically.

    curl -X POST https://api.fundmysquad.com/partner/v1/fundraisers \
      -H "x-partner-api-key: fms_partner_abc123..." \
      -H "Content-Type: application/json" \
      -d '{ "title": "Tigers Candy Sale", "goalAmount": 2000, "externalId": "team_8472", "shopEnabled": true }'
    

    Payouts required: a shop only accepts orders once the creator finishes Stripe Connect onboarding. Until then checkout returns PAYOUT_NOT_CONFIGURED.

    Three ways to stock a shop: a pre-configured bundle (simplest), individual catalog products by id, or fully custom products you supply & ship.

    Catalog & Bundles

    Browse the same platform-fulfilled products website users pick from.

    List catalog products:

    GET /partner/v1/catalog/products
    
    Returns { products: [{ id, title, description, images, minRetailPrice, shippingCost }] }. Use a product's id as platformProductId when adding it.

    List bundles (curated packs):

    GET /partner/v1/catalog/bundles
    
    Returns each bundle with the catalog products it contains.

    Add a whole bundle in one call:

    POST /partner/v1/fundraisers/:id/bundles
    
    Body: { "bundleId": "best-sellers" }. Each product is added at its default price; products already on the fundraiser are skipped (safe to re-run).

    Requires products:read to browse, products:write to add.

    Manage Products

    Add a product:

    POST /partner/v1/fundraisers/:id/products
    
    What you pass determines the type:
  • platformProductId — a catalog product by id (FMS fills in title/cost/images & fulfillment; retailPriceCents optional, must be ≥ the catalog minimum)
  • source: "custom" + title, retailPriceCents (optional baseCostCents, shippingCostCents, images) — your own product
  • source: "printful" or "goody" + externalProductId, title, baseCostCents, retailPriceCents

    All amounts are cents on input. FMS validates the margin and returns an earnings breakdown.

    List / update / delete:

  • GET    /partner/v1/fundraisers/:id/products
    PATCH  /partner/v1/fundraisers/:id/products/:productId
    DELETE /partner/v1/fundraisers/:id/products/:productId
    
    Delete hard-removes a product with no orders, otherwise deactivates it.

    Product Orders

    List orders:

    GET /partner/v1/fundraisers/:id/orders?status=&source=&limit=50&offset=0
    
    Each order includes product title, buyer, quantity, amount, fulfillment status, and tracking.

    Single order:

    GET /partner/v1/fundraisers/:id/orders/:orderId
    

    Product sales also appear in fundraiser stats (a productSales block + combinedRaisedAmount) and in GET /partner/v1/summary. Requires products:read.

    Endpoint Reference

    MethodEndpointScopeDescription
    POST/partner/v1/fundraisersfundraisers:writeCreate a fundraiser
    GET/partner/v1/fundraisersfundraisers:readList all fundraisers
    GET/partner/v1/fundraisers/:idfundraisers:readGet fundraiser details
    GET/partner/v1/fundraisers/by-external-id/:externalIdfundraisers:readLookup by external ID
    PATCH/partner/v1/fundraisers/:idfundraisers:writeUpdate a fundraiser
    POST/partner/v1/fundraisers/:id/closefundraisers:writeClose a fundraiser
    POST/partner/v1/fundraisers/:id/reopenfundraisers:writeReopen a fundraiser
    GET/partner/v1/fundraisers/:id/donationsdonations:readList donations
    GET/partner/v1/fundraisers/:id/statsfundraisers:readGet fundraiser stats
    GET/partner/v1/summaryfundraisers:readPartner portfolio summary
    POST/partner/v1/fundraisers/:id/connect/onboardfundraisers:writeStart Stripe Connect (per fundraiser)
    GET/partner/v1/fundraisers/:id/connect/statusfundraisers:readCheck Connect status (per fundraiser)
    POST/partner/v1/connect/onboardfundraisers:writeOnboard a reusable owner Connect account
    GET/partner/v1/connect/statusfundraisers:readOwner Connect status (by externalOwnerId)
    POST/partner/v1/fundraisers/:id/connect/linkfundraisers:writeAttach an owner Connect account to a fundraiser
    GET/partner/v1/catalog/productsproducts:readList platform catalog
    GET/partner/v1/catalog/bundlesproducts:readList pre-configured bundles
    POST/partner/v1/fundraisers/:id/bundlesproducts:writeAdd a bundle to a fundraiser
    POST/partner/v1/fundraisers/:id/productsproducts:writeAdd a product
    GET/partner/v1/fundraisers/:id/productsproducts:readList products
    PATCH/partner/v1/fundraisers/:id/products/:productIdproducts:writeUpdate a product
    DELETE/partner/v1/fundraisers/:id/products/:productIdproducts:writeRemove a product
    GET/partner/v1/fundraisers/:id/ordersproducts:readList product orders
    GET/partner/v1/fundraisers/:id/orders/:orderIdproducts:readGet an order

    Errors & Rate Limits

    Error format:

    { "error": "description of what went wrong" }
    

    StatusMeaning
    400Bad request — missing or invalid fields
    401Auth failed — bad or expired API key
    404Not found (or not owned by your partner)
    409Conflict — e.g. closing an already-closed fundraiser
    429Rate limit exceeded
    500Server error

    Rate limits: 120 requests/minute and 10,000 requests/day per API key.

    Rate limit headers on every response:

    HeaderDescription
    ---------------------
    X-RateLimit-LimitRequests allowed per minute
    X-RateLimit-RemainingRequests remaining in current window
    X-RateLimit-ResetUnix timestamp when the window resets
    Retry-AfterSeconds until retry (only on 429)

    Key Concepts

    External IDs: The externalId field bridges your platform and FMS. Pass your unique identifier for teams or users. Create multiple fundraisers for the same team and look them all up with one call.

    Partner Metadata: The metadata field is a free-form JSON object. Store league info, coach contacts, season details — FMS preserves it as-is.

    Scopes:

    ScopeGrants
    fundraisers:readList and view fundraisers
    fundraisers:writeCreate, update, close, reopen
    donations:readView donations
    products:readView catalog, products, and orders
    products:writeAdd, update, and remove products & bundles
    *All permissions

    Sandbox vs Production: Staging API keys create sandbox fundraisers (not public, no real donations). Production keys create real fundraisers that accept real donations.