spider_sdk 1.3.1
spider_sdk: ^1.3.1 copied to clipboard
Native Dart SDK for the Spider transit API — trip planning, stop search, and live realtime data.
Changelog #
1.3.1 - 2026-10-07 #
Changed #
- Fields the contract requires are non-null, as in the Kotlin, TypeScript and Swift SDKs:
Stop.lat,lon;LiveVehicle.tripId,latitude,longitude;ServiceAlert.id. Their constructor parameters arerequired.
1.3.0 - 2026-10-07 #
Targets Spider API contract 1.3.
Breaking #
realtime.delays(serviceDate, tripIds)takes one service date and callsGET /realtime/v1/delays?serviceDate=…&tripIds=….delaysByServiceDate,pollDelaysByServiceDateandServiceDateDelaysare removed;pollDelays(serviceDate, tripIds)takes the same arguments in the same order.TripDelaysis flat:serviceDate,delays,missing,freshness;delayFor(tripId)drops its date.TripDelay.tripIdis non-null.- Delays validate before sending: no ids is
tripIds is required, a blank idtripIds is invalid, more than 50 distinct idstripIds is out of range(allbadRequest, fieldtripIds). The ids are de-duplicated and sorted, so equal requests share one URL and its CDN cache. SpiderErrorCode.queryRetiredis removed. A 410 or aquery_retiredbody is no longer special-cased.RoutingErrorCode.noTransitConnectionInSearchWindowandoutsideBoundsare removed; the API no longer sends them.- Exact nullability. Fields the API always sends are non-null:
Leg.fromName,toName,distanceMeters;Itinerary.start,end,waitingTimeSeconds;Route.searchDateTime;Departure.realtimeTimeEpochMs,tripGtfsId,routeGtfsId,stopGtfsId;TripStop.lat,lonand the four stop times;TripDetails.routeGtfsId. Fields the API may null stay nullable. Leg.durationSecondsis anint, likeItinerary.durationSeconds.FeedFreshness.staleSecondsis anint.
Changed #
- Realtime ids are feed-prefixed (
<feedId>:<id>), exactly as routing returns them, and are sent and returned untouched.
1.2.0 - 2026-10-06 #
Targets Spider API contract 1.2.
Hard cut. Contract 1.2 moves routing from persisted GraphQL queries to REST and every customer path
under /v1. SDK 1.1 and earlier stop working against it: the API no longer serves their paths. The public API
keeps its shape.
Changed #
plan,planStream,departuresandtripcall the REST operationsPOST /routing/v1/plan,/routing/v1/plan-stream,/routing/v1/departuresand/routing/v1/tripwith the contract's JSON bodies. The public routing API (PlanOptions,Route,Departure,TripDetails,PlanStreamEvent) keeps its shape.- Stops and realtime calls use the
/v1paths:POST /stops/v1/search,GET /realtime/v1/vehicles,GET /realtime/v1/vehicles/by-trip/{id},POST /realtime/v1/delaysandGET /realtime/v1/alerts. SpiderErrorCode.queryRetiredis any HTTP 410 on every surface, or a body whosecode(or gatewayerror) isquery_retired, whatever the status. The message is the body's.SpiderError.fieldon a 400 is the body'sfield, else the dot path the message names (<path> is required,is invalid,is out of rangeoris not allowed), e.g.preferences.transit.transfer.maximumTransfers. A member the API does not take is<path> is not allowed.- A plan-limit refusal is read from the body's
code, else itserror. - A via visit waits at most 1 h (
minimumWaitSeconds0–3600, was 0–86400), as the API takes. Outside that the plan fails asbadRequestwith fieldvia.visit.minimumWaitTime, without a request. - A coordinate via visit fails before sending.
ViaLocation.visit(Location.coordinate(...))isbadRequestwith messagevia is invalidand fieldvia, the answer the API already gave; a visit takes a stop. planStreamignores event names it doesn't know, so the API can add events. A stream cut before its paging info, whether it ends or the connection drops, ends with aPlanStreamFailure(network). Nothing follows the terminalPlanStreamDoneorPlanStreamFailure. A non-2xx answer before the stream maps like the one-shot calls.- A large response is decoded off the UI isolate. A body of 50 KB or more is decoded and mapped (plan polylines included) on a background isolate, so a Flutter UI never spends a frame on it. Web decodes inline.
Deprecated #
RouteEdge.cursoris always"NoCursor"; page withRoute.pageInfothroughplanNext/planPrevious.Itinerary.accessibilityScoreandLeg.accessibilityScoreare always null.
Removed #
- The persisted-query transport, and the
persisted_query_rejectedserverCodeon a 403, which the API no longer sends: a 403 that isn't a plan-limit refusal isunauthorized, like any other. No public symbol is removed.
1.1.0 - 2026-10-05 #
Targets Spider API contract 1.1.
Added #
PlanOptions.reliabilityforplanandplanStream: each arrival is planned with the trip's typical delay at the stop from the environment's realtime history, the median atReliability.standard, the 70th percentile atsafeand the 90th atverySafe. Boarding keeps the scheduled departure, and a trip with live realtime uses its realtime times. Left null, the plan follows the timetable and noreliabilityis sent.Leg.typicalArrivalDelay: the delay planned into the leg's arrival; null withoutreliabilityor when the trip has no delay history.Departure.typicalDelayandTripStop.typicalDelay: the median delay at the stop for that trip on the service date's day type; null when there is no history.Leg.interlineWithPreviousLeg: the rider stays on the same vehicle from the previous leg as it carries on as another trip, often under another line. That change isn't counted innumberOfTransfers.
Changed #
plan,planStream,departuresandtripsend the contract1.1persisted queries. The1.0queries stay served until 2027-07-01, so earlier SDK versions keep working until then.
1.0.0 - 2026-10-01 #
Targets Spider API contract 1.0. The first stable release: from here on, breaking changes need a new major.
Changed #
planStream/planStreamNext/planStreamPreviousrequiretargetResults:andmaxWindowMinutes:. There is no SDK default;maxWindowMinutesmust be at least 120.WheelchairBoardingandBikesAllowedgainunknown, so every decoded enum (TransitMode,OccupancyStatus,RealtimeState,RoutingErrorCode,InputField,WheelchairBoarding,BikesAllowed) maps a value this SDK version doesn't know tounknowninstead ofnull.NO_INFORMATION/NO_DATA_AVAILABLEstaynull. An exhaustiveswitchon either enum needs theunknowncase.- HTTP 400 is
SpiderErrorCode.badRequeston every surface (it wasunknown), withSpiderError.fieldset when the server's message names the input. - Invalid input is rejected before any request, as
badRequestnaming only the field (e.g.maxWindow is out of range) withfieldset: a stream window under 120 minutes, a departurestimeRangeSecondsoutside (0, 86400], more than 50 realtime trip ids across all service dates, a malformedserviceDateontripordelays/delaysByServiceDate, a stop-searchlimitoutside 1–50, a via pass-through without 1–10 stop ids, or a visit wait outside 0–86400 s. Nothing is clamped. - Departures always send 30 departures over 24 h unless told otherwise (
timeRangeSecondsis a non-nullint), and stop search always sendslimit(20 unless told otherwise;StopFilter.limitand thelimitofnear/withinare non-nullints). - A plan stream the gateway rejects before routing (e.g. a missing variable) fails as
badRequestnaming the field, like the batch call. - An unknown persisted-query id (403
persisted_query_rejected) staysunauthorizedand keeps the gateway's message.
Added #
SpiderErrorCode.queryRetiredfor a persisted query the API no longer serves (HTTP 410). It used to arrive asunauthorized. An exhaustiveswitchonSpiderErrorCodeneeds the new case.SpiderErrorCode.planningLimitReachedwhen the project has reached its plan's trip planning limit. Trip planning (plan,planStream) is refused and the other calls still work.SpiderErrorCode.agreementInactivewhen the project has no active agreement. Every call made with the key is refused. Both come from the response body's code whatever the HTTP status, on every surface (including a plan stream refused before it starts), withhttpStatusandserverCodeset. AvehicleForTrip404 that carries one is that error, not "no vehicle". The message is the body's; when the body has none, it istrip planning limit reachedoragreement is not active. A 403 without one of these codes staysunauthorized. An exhaustiveswitchonSpiderErrorCodeneeds both cases.- Display fields.
Leg:routeGtfsId,routeColor,routeTextColor,fromPlatformCode,toPlatformCode,fromZoneId,toZoneId.Departure:routeGtfsId,routeColor,routeTextColor,stopGtfsId,platformCode,wheelchairAccessible.TripDetails:routeGtfsId,routeColor,routeTextColor,wheelchairAccessible.TripStop:platformCode,zoneId. Colours are the feed's GTFS hex without#. Departure.serviceDateandTripDetails.serviceDate(ISOYYYY-MM-DD), to scope a realtime delay lookup or atrip(serviceDate:)call.PlanStreamDone.routingErrors, likeRoute.routingErrors. AlocationNotFoundnamesInputField.from,toorvia.- Stops:
Stop.code,Stop.locationType,Stop.wheelchairBoarding,Stop.modes, andStopFilter.modes(stops served by at least one of the modes). Search text also matches a stop's code, town and district.
Removed #
SpiderContractMismatchError: a gateway declaring another contract major is no longer an error, so every call reports its failures throughSpiderResult.- The departures filter that dropped rows whose headsign equals the stop name.
0.7.1 - 2026-09-25 #
Targets Spider API contract 0.7.
Changed #
SpiderRouting.planStream(...)streams the initial window only and emits a three-variantStream<PlanStreamEvent>:PlanStreamResult(itineraries)for each batch of finalized itineraries, a terminalPlanStreamDone(pageInfo)carrying the continuationRoutePageInfo(endCursor/startCursor/hasNextPage/hasPreviousPage), or a terminalPlanStreamFailure(error).- Continue a stream with
planStreamNext(options, after:)/planStreamPrevious(options, before:)— each repeatsplanStream's parameters plus a raw cursorStringread offPlanStreamDone.pageInfo.planStreamno longer takesafter/before.
Removed #
planUntil/planNextUntil/planPreviousUntil— the client-side window-walkers. Drive continuation fromPlanStreamDone.pageInfo(stream) orplanNext/planPrevious(batch) instead.PlanStreamChunkandPlanStreamPage, folded intoPlanStreamResultandPlanStreamDone; the internal sweep telemetry (frontierSeconds/found/finalized,iterations/windowSeconds/resultCount/stoppedBy) is no longer surfaced.
0.7.0 - 2026-09-24 #
Targets Spider API contract 0.7. Brings the Dart SDK to parity with the reference SDK.
Added #
SpiderRouting.planStream(...)— streams itineraries over Server-Sent Events as the router sweeps the search window forward, emitting aStream<PlanStreamEvent>(PlanStreamChunk/PlanStreamPage/PlanStreamDone, or a terminalPlanStreamFailure) instead of one batched page. Cold and cancellable;targetResults/maxWindowMinutespace the sweep,after/beforecontinue from a prior page's cursors.SpiderClient.warmup()— pre-warms the connection to the environment's API host with oneGET /ping(authenticated with the client apikey), so the first trip-planning call rides an already-open TLS connection. Best-effort and never throws; returns the measured round-tripDuration.Legrealtime fields —startEstimated/endEstimated,startDelay/endDelay,isRealtime,realtimeState, andserviceDate(the GTFS service date to scope a delay lookup by), plusfromGtfsId/toGtfsId. Surfaced by bothplanandplanStream.
Changed #
- Realtime delays are now grouped by service date.
realtime.delays(tripIds, serviceDate)andrealtime.delaysByServiceDate({serviceDate: tripIds})POST a grouped query so the same trip id on two service dates resolves to two distinct instances; look one up withTripDelays.delayFor(tripId, serviceDate).TripDelays.groupsreplaces the flatdelays/missing.pollDelaysmirrors the change. The flatdelays(tripIds)is removed.
Fixed #
maxTransfersnow maps to the router's boarding count (maximumTransfers = transfers + 1). The router indexes legs with leg 0 as the initial access (walk, or nothing), so passing the caller's transfer count verbatim mademaxTransfers0 and 1 behave identically. Now0means direct,1allows one transfer.
0.1.1 - 2026-08-26 #
Breaking: searchWindow is now required on plan requests (the gateway enforces the
updated contract, and older persisted-query ids are rejected with 403).
- Persisted queries updated to the current published contract.
- Server-side validation failures now surface as
SpiderErrorCode.badRequest.
0.1.0 - 2026-08-22 #
Initial public pre-release; targets Spider API contract 0.1.
This is a pre-1.0 release: the API surface may change without a major-version bump until 1.0.0. Pin an exact version if you need stability.
Covered surfaces:
- Trip planning (
planConnection) — itineraries with paging. - Stop departures — upcoming departures for a stop.
- Single-trip lookup — a trip's stops and times.
- Stop search — free-text/autocomplete and geographic (nearest, radius, bounding box) queries, plus lookup by GTFS id.
- Realtime (poll-based) — vehicle positions, delays, and service alerts.