Developer documentation
Grant Data API v1
A REST API over Mavenly's normalized grant index. All responses are JSON, all dates are ISO 8601 UTC, and all monetary values are whole USD numbers.
Interactive playground
Sign in and we issue a sandbox key for your workspace automatically, so every live call is metered against your own account. Pick an endpoint, tune the parameters and run it — without a key you still get the documented sample response instantly.
Base URL
https://uzclgwsoxozyvpiodhho.supabase.co/functions/v1/api-v1
Authentication
Every request carries an API key issued from your Mavenly workspace under Integrations → API access. Keys are shown once at creation; only a hash is stored. Send the key in the Authorization header.
curl "https://uzclgwsoxozyvpiodhho.supabase.co/functions/v1/api-v1/v1/opportunities/search?agency=HRSA&limit=5" \ -H "Authorization: Bearer mav_live_xxxxxxxxxxxxxxxx"
Keys are scoped read or read_write, and to either the sandbox or live environment. Sandbox keys return the same schema against a capped slice of the index.
Endpoints
Filter by agency, source, opportunity number, focus area, award range, closing window or last-updated timestamp.
Retrieve one opportunity by Mavenly id, slug or opportunity number, with parsed eligibility, dates and financials.
AI-extracted breakdown: scoring rubric weights, statutory priorities, evidence tier, mandatory attachments, red flags.
Submit an organization profile and receive score-weighted opportunities with the reasons behind each score.
List your webhook subscriptions and their last delivery status.
Subscribe to opportunity.created, opportunity.amended and deadline.extended events, signed with HMAC-SHA256.
Current plan, monthly quota, requests used this period and your per-second rate limit.
Searching opportunities
Combine any of these query parameters. Results are ordered by closing date ascending unless sort=posted_desc is supplied.
| q | Full-text query across title and summary |
| agency | Agency name or abbreviation |
| source | grants_gov · sam_gov · nsf · federal_register |
| opportunity_number | Exact agency opportunity number |
| focus | Focus tag, repeatable |
| min_award / max_award | Award floor and ceiling filters in USD |
| closing_before / closing_after | ISO 8601 date bounds |
| updated_since | Cursor for incremental sync |
| limit / cursor | Page size (max 100) and pagination cursor |
Webhooks
Subscribe an HTTPS endpoint and Mavenly posts events as they are detected. Each delivery includes an X-Mavenly-Signature header containing an HMAC-SHA256 of the raw body using your subscription secret. Verify it before trusting the payload. Non-2xx responses are retried with backoff.
POST https://uzclgwsoxozyvpiodhho.supabase.co/functions/v1/api-v1/v1/webhooks/subscriptions
Authorization: Bearer mav_live_xxxxxxxxxxxxxxxx
Content-Type: application/json
{
"url": "https://your-app.example.com/hooks/mavenly",
"events": ["opportunity.created", "opportunity.amended", "deadline.extended"]
}Rate limits and errors
Responses carry X-RateLimit-Limit, X-RateLimit-Remaining and X-RateLimit-Reset. Exceeding your per-second limit returns 429 with a Retry-After header; exhausting your monthly quota returns 402.
| 400 | invalid_request — malformed parameters |
| 401 | unauthorized — missing, revoked or unknown key |
| 402 | quota_exceeded — monthly request limit reached |
| 403 | plan_required — endpoint not included in your tier |
| 404 | not_found — no opportunity with that identifier |
| 429 | rate_limited — slow down and retry after the header value |
| 500 | server_error — transient; retry with backoff |
Developer sandbox
Sandbox keys are free, start with mav_test_, and are capped at 500 requests a month, 2 requests a second and 10 results a page. They hit the same endpoints and return the same schema as live keys, and they are metered per key, so a sandbox key never spends a paid quota.
- 1. Sign in to Mavenly and open Integrations → API access.
- 2. Choose the Sandbox environment and create a key — it is shown once.
- 3. Paste it below and walk each step to see real requests, real headers and real error shapes.
- 4. When you are ready, swap in a live key from a Developer or Professional plan; no code changes are required.
Held in this browser tab only. Nothing is stored or logged by this page.
1 · Confirm your key
Returns your plan, environment, monthly allowance and requests used so far. Start here — a 401 means the key was copied incorrectly or revoked.
GET /v1/usage2 · Search opportunities
Sandbox keys see the same normalized schema, capped at 10 results per page. Unknown parameters are rejected with a 400 and a per-field errors array.
GET /v1/opportunities/search?open_only=true&limit=5&sort=closing_date3 · Retrieve one opportunity
Take an opportunity_id from step 2 and fetch the full record. Ids, slugs and agency opportunity numbers all resolve.
GET /v1/opportunities/REPLACE_WITH_OPPORTUNITY_ID4 · See a validation error
Deliberately sends an unsupported parameter so you can wire up your error handling against a real 400 response before going live.
GET /v1/opportunities/search?not_a_param=1&limit=abc5 · Try a plan-gated endpoint
The AI dissection endpoint is Professional and above. On a sandbox key this returns 403 plan_required — the exact shape your upgrade path should handle.
GET /v1/opportunities/REPLACE_WITH_OPPORTUNITY_ID/dissection