SharpRelayPinnacle data
HomeAPI referenceDashboard

Frequently asked questions

Keys & account

I lost my API key. Can you show it to me again?

We cannot look up an old plaintext key. If you still have any account:manage key, create a replacement or rotate through the dashboard. Direct API rotation requires a fresh 32-byte rot_… Idempotency-Key; keep the old key and nonce until the response is safely stored because that exact pair can recover an interrupted delivery for 15 minutes.

If every management key is gone, use the secure recovery page. A link can be issued only if the exact current account mailbox was explicitly verified before the final management key was lost. Unknown and unverified addresses receive the same generic accepted response, but an unverified request creates no recovery link. The request is resolved asynchronously through an encrypted blind queue, so allow a few seconds for an eligible verified buyer's 30-minute fragment-only email link. Claiming it revokes all existing keys and issues one full-management replacement; the exact link bearer can recover an interrupted response for 10 minutes. The replacement is shown only on the first-party page and is never emailed. Suspended, canceled, held, unverified, reconciliation-required, or expired-grace accounts require support. Never send us the recovery link itself.

Why do I need to verify the recovery email separately?

Possession of an account email address is not proof that its mailbox owner should be able to recover your account. Separate, explicit verification prevents an unconfirmed address from gaining authority to trigger the all-key replacement flow. Verification itself changes no API key; it only authorizes the exact current mailbox for a possible future recovery.

I did not receive the recovery-email verification message. What now?

While you still have an account:manage key, open the dashboard and choose Send verification email. Requests are limited to one per customer every 10 minutes, links are single-use and expire after 24 hours, and the generic accepted response does not guarantee that a new message was sent. Check the account mailbox and its spam filtering. If you have already lost every management key and the mailbox was never verified, contact support; the public recovery form will deliberately issue nothing.

How many keys can I have?

Up to 5 active keys per account. Create named keys per system (production, staging, research) in the dashboard, and revoke any of them independently.

Which permissions should an application key have?

Use a data:read-only key for pollers, services, and analytics jobs. It can retrieve odds but cannot inspect your account or create, revoke, or rotate credentials. Keep a key with account:manage in your secrets manager for the dashboard and key administration. New dashboard keys default to data-only.

Quota & billing

How do I update payment details or manage my subscription?

For a paid account, sign in to the buyer dashboard with an account:manage key and choose Manage billing. This creates a fresh short-lived Stripe-hosted session for payment details, invoices, and the configured cancellation flow. The link should not be logged, bookmarked, or shared. Private beta access has no card, charge, renewal, or paid subscription to manage. Contact support for access or plan changes.

What exactly does one API call cost?

On ordinary routes, one credit includes up to 20 returned rows; every additional started 20-row block costs one more credit, and an empty result costs one credit. Verified live=1 discovery is variable: it charges the greater of returned-row credits and bounded discovery/offer-check work through the same 20-unit blocks. Narrow its filters and limit to control that work. Every metered response reports the authoritative final amount in X-Credits-Cost. See Quotas & metering.

What happens when I exhaust my quota?

Calls return 429 quota_exceeded with a Retry-After header counting down to the first applicable daily or plan-period reset. Your key is never deleted for overuse — service resumes automatically at reset. A private-beta limit change or extension requires a separately reviewed and approved offer; paid plan changes use the documented paid flow. A request that cannot reserve its certified maximum charge is rejected before data work and does not consume buyer credits.

Do cached responses cost credits?

Yes — metering is per request/row regardless of cache path (that's what keeps usage accounting simple and predictable). The benefit of cache is avoiding the source round trip, not a guaranteed latency or lower credit cost. To spend fewer credits, poll incrementally with since — see Polling & performance.

Data & freshness

Where does the odds data come from?

The feed is sourced from Pinnacle. SharpRelay provides the independent delivery layer around it: a stable REST contract, buyer API keys, hard quotas, caching, request tracing, and normalized failures. SharpRelay is not affiliated with, endorsed by, or sponsored by Pinnacle.

How fresh are the odds?

Timeline endpoints (/v1/events/{event_id}/odds, /v1/props/{prop_id}/odds) bypass the response cache and request the current source view; actual freshness and availability still depend on source and network conditions. Reference endpoints are cached briefly (ordinary fixtures and closing/results ~30s, sports/leagues ~1h, and non-empty opening snapshots up to 24h); outright discovery is cached for roughly five minutes. Verified live=1 discovery is not response-cached: every request freshly retrieves source candidates from the complete bounded boundary, then performs bounded per-page verification. Every returned event has live_status=1; its latest odds are bound to that event and contain an open line whose cutoff remains strictly future when expiry is rechecked at final validation. No arbitrary update-age or kickoff-age rule is imposed. Empty opening, closing, and result responses are not cached. Closing lines and results can be corrected or re-settled, so refresh them whenever revisions matter. The X-Cache header shows which cache path served your response when the disposable cache is available; an absent header can also mean the route bypassed cache, caching was disabled, or that cache was unavailable.

Why did event discovery return only future fixtures?

That is the safe default for ordinary GET /v1/events. A present or future starts_from remains locally enforced as a future lower bound; only a genuinely past value opts into historical discovery. Pair it with starts_to to set a locally enforced inclusive timestamp or complete UTC-day upper bound. An exact event_id or parent_id lookup targets that identifier's lifecycle directly. Use live=1 for currently verified in-play offers rather than widening a historical fixture window. Without an explicit window or identifier, starts must remain strictly after the request boundary and in the future at final validation.

Which prop operations are available in the private beta?

The v1 beta publishes 12 authenticated, read-only data routes. Discover event props through /v1/events/{event_id}/props, then use each returned special_id as prop_id to request latest or available historical prices from /v1/props/{prop_id}/odds. Discover outrights through /v1/outrights and price each returned ID the same way. Event-wide bulk prop prices and prop-specific opening, closing, results, and CLV operations are not exposed in the v1 private beta.

What sports and markets are covered?

Coverage follows the currently available source catalog. Call /v1/catalog/sports for the current list and /v1/catalog/leagues?sport_id=… for available leagues. Returned markets can include moneyline, spreads, totals (full match and per-period), player/team specials, and outrights where available for that sport, event, source state, and plan. Catalog responses can be served from the disposable cache for roughly one hour, so inspect X-Cache and refresh on a slow timer rather than treating the response as zero-staleness.

How much history is available?

Historical depth varies by sport, event, market, and source availability. Event odds default to every primary and alternate market row at the greatest positive line_id for each event and period; older off-board line IDs are excluded. Prop odds default to one greatest-line_id row per special_id + contestant_line_id, with handicap treated as a value on that row rather than a separate latest identity. Use full_history=1 to request available matching history. Event odds additionally accept a moving since timestamp for incremental history (budget credits for the row volume). Use since by itself or with full_history=1; since=...&full_history=0 is rejected. Always inspect X-Result-Truncated and do not assume a historical response is complete. Use /v1/events/{event_id}/lines/opening and /v1/events/{event_id}/lines/closing for available first/last lines. These options do not guarantee a complete event history.

Troubleshooting

I'm getting 401s with a valid-looking key.

Check for whitespace/newlines when pasting, confirm the key is active in the dashboard, and make sure you're sending Authorization: Bearer sr_live_… (not the key ID shown in tables). If it was recently rotated, the old key is dead by design.

Something looks wrong — how do I report it?

Include the request_id from the error envelope (or the X-Request-Id header of the suspicious response) and the UTC time. With those we can trace the exact request end to end.