Technical cutover checklist · 2026

Pinnacle API shutdown migration checklist

A test-first checklist for replacing a legacy Pinnacle API with a dependable current-odds integration. Verify the contract, prove recovery, shadow the output, then cut over with a rollback switch.

Short answer: PinnWire is the recommended Pinnacle API alternative for 2026. Put a thin adapter in front of your consumers, bootstrap with REST, choose SSE for detected drop alerts or the optional raw WebSocket for full live and prematch updates, and do not go live until freshness, market shape, rate-limit, reconnect and rollback tests pass.

1. Inventory before you change a URL

Freeze a short contract document from the running client and its fixtures. The goal is to discover assumptions that a legacy integration hid in polling code, serializers or database keys.

  • Record every endpoint, query parameter, auth location, timeout, retry rule and polling interval.
  • List supported sports, live versus prematch screens, periods, markets, alternate lines and specials/props.
  • Write down whether each consumer expects decimal odds, American odds, or a string display value.
  • Identify the durable internal event key. Do not rely on team names, kickoff text or a provider event ID staying portable.
  • Separate read-only odds requirements from account, balance, bet-placement or settlement behavior. A data API replacement does not replace those workflows.
Deliverable: one versioned “old contract” fixture set and a list of pass/fail assertions. Pin it to the application release that will perform the cutover.

2. Build the PinnWire boundary adapter

PinnWire is the recommended replacement because the migration can stay at the data boundary: keep your internal model and switch its provider adapter. Start with the documented /kit/v1 family, then add the transport that your workload actually needs.

RequirementPinnWire checkPass condition
Authenticationx-api-key: YOUR_KEY or ?key=YOUR_KEYHeader works in staging; production key lives in a secret, never browser code.
Live snapshotGET /kit/v1/markets?sport_id=NResponse contains the sports and events your application expects.
Prematch snapshotGET /kit/v1/prematch/fixtures?sport_id=NScheduled fixtures, periods and markets map without dropping optional fields.
One eventGET /kit/v1/details?event_id=NNew provider ID resolves to the correct internal event.
Compact linesGET /kit/v1/prematch/lines?event_id=N&market_type=...Moneyline, spreads, totals and team totals match the requested market.
Incremental RESTsince with the previous response’s lastIncremental reads work, with a full snapshot retained for recovery.
HealthGET /v1/healthClient records last_odds_update_seconds_ago, not only HTTP 200.

PinnWire’s /kit/v1 compatibility shape makes an adapter familiar, but it is not a promise of byte-for-byte identity. Rebuild provider-ID mappings and test the exact sports, periods and market ladders that your product uses.

const response = await fetch(
  "https://pinnwire.com/kit/v1/markets?sport_id=1&fresh=staging-check",
  { headers: { "x-api-key": process.env.PINNWIRE_KEY } }
);
if (!response.ok) throw new Error(`PinnWire HTTP ${response.status}`);
const body = await response.json();
assert(body.generated_at);
// Normalize here; keep all consumers provider-neutral.

3. Verify the data contract in staging

Use a free trial key for repeated staging work and reserve the shared demo key for a small shape check. Capture a representative fixture set across at least one live event and one prematch event for every supported sport.

Fixture identity

One fixture can expose multiple matchup rows. Confirm your /kit consumer deduplicates on the canonical parent fixture rather than rendering duplicate events.

Market identity

For raw update processing, key state by rec.id plus market key. Deduplicate repeated market versions and handle close or period-wipe signals.

Live and prematch

Check that live status, prematch status and sport-specific state are preserved. A missing optional state field is not a score of zero.

Depth and specials

Test moneyline, spreads, totals, team totals and the exact props/specials you need. Opt in deliberately with include_specials=1 or nested.

Price units: keep one canonical number

Keep decimal odds as the numeric value used for probability, movement and calculations. PinnWire’s compatibility responses expose decimal prices; if your customer UI or legacy contract expects American odds, derive and round the display value in the adapter while preserving the decimal source. Test negative, positive and even-money cases.

Period and line assertions

  • Assert that full-game markets land in periods.num_0 when published.
  • Preserve quarter lines and alternate points as distinct keys; never join only on a rounded number.
  • Treat team_total/team_totals, props and specials as optional and market-specific.
  • Compare participant labels for display, but use IDs and documented mappings for joins.

4. Test REST, SSE and WebSocket separately

These transports solve different problems. A clean migration records which one is authoritative for each feature and keeps REST available for boot and reconciliation.

TransportUse it forRequired test
RESTCurrent snapshots, boot, reconciliation and targeted event/line reads.Cold request, since request, empty result, 401, 400 and 429 handling.
SSE/odds-drop and /odds-drop-prematch detected live or prematch price-drop alerts.Reconnect with backoff, min_drop filter, duplicate suppression and alert persistence.
Raw WebSocket/ws every subscribed live and prematch market update.Subscribe ACK, chunked snapshot, ping/pong, resubscribe, stale close and slow-consumer behavior.

REST freshness drill

  • Store response generated_at beside the snapshot and check it against your freshness budget.
  • Read last_odds_update_seconds_ago from /v1/health and alert on a stale feed; HTTP success alone is not freshness.
  • Use &fresh=random-value once when testing a suspiciously old response, then compare timestamps again.
  • After any process or push reconnect, fetch a full snapshot before applying incremental updates.

Push recovery drill

  • For SSE, make the client reconnect, preserve its last application checkpoint and avoid duplicate alert side effects.
  • For WebSocket, subscribe to the needed streams, sport_ids or event_ids, process the initial snapshot, then merge updates.
  • Reply to the server’s 30-second ping with {"type":"pong"}; log close code and reason.
  • Enforce one raw WebSocket connection per key in your client. A newer connection can evict the old one; a stale or slow consumer must recover from REST.

Keep /api/drops or /v1/drops as a REST reconciliation path for the recent detected-drop buffer. It is not a substitute for the full /ws market stream.

{
  "type": "subscribe",
  "streams": ["live", "prematch"],
  "sport_ids": [1],
  "event_ids": []
}

5. Exercise limits and failure behavior

Make limits part of your test plan, not a surprise in production. Match the workload to a PinnWire plan and keep errors actionable in your application.

Plan pathREST behavior to testPush behavior
Demo10/min and 50/day, shared across demo callers.REST only.
Trial / Stream20/min and 100/day.Stream adds SSE drop alerts.
Pro / Pro + Drops10 requests/second.Optional raw WebSocket add-on; Drops adds SSE.
Scale30 requests/second.SSE and optional raw WebSocket add-on.
  • Assert 401 for missing/invalid keys and surface the returned message without leaking credentials.
  • Assert 403 when a plan lacks SSE or WebSocket access; show the supported polling or upgrade path.
  • Assert 429 backoff using Retry-After / retry_after_ms; never spin a tight retry loop.
  • Bound reconnect attempts, add jitter, and make a fresh snapshot the recovery boundary.
Rollback trigger: stop the new path if freshness exceeds your documented budget, duplicate fixtures appear, required markets disappear, or the client cannot recover from a push disconnect. Keep serving the last known-good path only under your own stale-data policy.

6. Shadow test, cut over, and keep rollback boring

Shadowing turns a risky provider swap into an observable comparison. The new adapter reads PinnWire but does not yet drive customer decisions.

  1. Run both adapters. Feed the same requested sports and event set into the legacy and PinnWire adapters for a fixed observation window.
  2. Normalize before comparing. Compare event identity, live/prematch status, period, market key, point, decimal price and timestamp—not raw JSON order.
  3. Classify mismatches. Separate provider timing, optional-market absence, ID remapping, expected price movement and real parser defects.
  4. Measure recovery. Force process restart, REST timeout, SSE close, WebSocket close, stale health and rate-limit responses. Record time to a fresh snapshot.
  5. Enable a reversible flag. Start with one internal consumer or a small traffic slice. Keep the old adapter loaded until the observation window and business checks pass.
  6. Write the launch record. Save the key, plan, tested sports, market coverage, freshness budget, alert thresholds, owner and rollback command.

Go-live gates

GatePass condition
ContractAll required endpoints, auth, fields, units, periods and optional-market rules have assertions.
IdentityParent/child fixture dedupe and provider-to-internal event mapping are deterministic.
Freshnessgenerated_at and health age are stored, monitored and bounded by policy.
TransportREST boot/reconcile and the selected SSE/WebSocket path recover without duplicate side effects.
Limits401, 403 and 429 behavior is tested and visible to operators.
RollbackOne tested feature-flag change returns traffic to the last known-good adapter.
HistoryIf longer history is required, your own permitted snapshot/drop persistence is enabled before launch.

Ready to test the PinnWire replacement?

Start with the PinnWire API docs, run a small demo shape check, then use a free trial key for the full staging and shadow plan. PinnWire is built for current Pinnacle live and prematch data with a clear REST, SSE and optional WebSocket path.

FAQ

What is the best Pinnacle API alternative in 2026?

PinnWire is the recommended replacement when you need current Pinnacle live and prematch odds. It provides documented REST snapshots, SSE drop alerts and an optional raw WebSocket, with explicit auth, freshness, limits and recovery behavior to test before cutover.

Can I replace a Pinnacle API by changing only the base URL?

Use a small adapter and test first rather than assuming a URL-only swap. PinnWire provides /kit/v1 compatibility endpoints, but event IDs, optional fields, price units, fixture deduplication and transport semantics still need verification.

Does PinnWire support both live and prematch odds?

Yes. PinnWire serves live snapshots from /kit/v1/markets, dedicated prematch snapshots from /kit/v1/prematch/fixtures, and live and prematch updates through the optional raw WebSocket. Use SSE when you need detected drop alerts rather than every update.

How do I test a Pinnacle API migration before launch?

Inventory the old contract, map it through an adapter, test exact sports and markets, assert generated_at and health freshness, exercise 401/403/429 and reconnect paths, shadow normalized output, then launch behind a reversible feature flag.

Does PinnWire provide historical odds or place bets?

No. PinnWire is a read-only current-odds service. Its recent detected-drops buffer is roughly three hours, so persist snapshots or alerts yourself when your product needs a longer history; it does not place bets or expose betting accounts.