Deep-link imports
Build an "Edit in GTFS·X" button. One URL opens any GTFS feed in the editor — no upload, no download, no account.
What it is
GTFS·X accepts inbound URLs that name a GTFS feed by direct ZIP URL or by catalog id. A click on such a link fetches the feed server-side, validates that it parses as GTFS, and drops the user straight into the editor. Designed for catalogs (Mobility Database, transit.land), validators, blog posts, and cold-email outreach.
Quick start
1. Direct feed URL
https://www.gtfsx.com/import?url=https%3A%2F%2Fexample.org%2Fgtfs.zip
URL-encode the feed URL (use encodeURIComponent in JavaScript). HTTPS feeds preferred; HTTP is accepted but discouraged.
2. Mobility Database feed id
https://www.gtfsx.com/import?source=mobilitydb&feed_id=mdb-1234
We resolve feed_id to the feed's latest hosted dataset via the Mobility Database API, then load it. Use the id field from the catalog (e.g. mdb-1234).
3. transit.land Onestop id
https://www.gtfsx.com/import?source=transitland&onestop_id=f-9q9-bart
Status: not yet wired up — requires a transit.land API key on our end. Coming soon. Use the direct-URL variant in the meantime.
URL parameters
| Parameter | Required? | Description |
|---|---|---|
url |
Yes for direct imports | URL-encoded GTFS .zip URL. Mutually exclusive with source. |
source |
Yes for catalog imports | Catalog name. Currently mobilitydb; transitland coming soon. |
feed_id |
With source=mobilitydb |
Mobility Database feed id, e.g. mdb-1234. |
onestop_id |
With source=transitland |
transit.land Onestop id, e.g. f-9q9-bart. |
ref |
Optional | Attribution tag. Recorded in our analytics. Known partner refs (mobilitydb, transitland, gtfs_validator) also render a "Loaded from ..." badge on url-based imports. Not needed for catalog-source imports -- the badge appears automatically based on source. |
Button snippets
Text link
<a href="https://www.gtfsx.com/import?url=https%3A%2F%2Fexample.org%2Fgtfs.zip&ref=YOUR_REF">Edit in GTFS·X</a>
Logo button
Renders like this:
<a href="https://www.gtfsx.com/import?url=https%3A%2F%2Fexample.org%2Fgtfs.zip&ref=YOUR_REF"
style="display:inline-flex;align-items:center;gap:10px;
background:#E8734A;color:#fff;padding:10px 18px;
border-radius:8px;text-decoration:none;font-weight:600;
font-family:ui-sans-serif,system-ui,-apple-system,sans-serif;">
<img src="https://www.gtfsx.com/gtfsx-mark.svg"
alt="" width="24" height="24" />
Edit in GTFS·X
</a>
Use the logo SVG at https://www.gtfsx.com/gtfsx-mark.svg. Square aspect, transparent background, hot-link friendly.
Errors and edge cases
The /import page handles every common failure mode with a user-facing message and a path forward. Partners don't need to validate URLs themselves; just hand off and we'll show the right error.
| What happens | What the user sees |
|---|---|
| Missing or malformed parameters | "We need a GTFS feed URL to import." + upload fallback |
| Fetch timed out (>30 s) or returned non-200 | "Couldn't reach the feed at [URL]." + retry / paste-URL |
| Response isn't a ZIP | "That URL didn't return a GTFS zip file." + upload fallback |
| ZIP isn't valid GTFS | "We got a ZIP but it doesn't look like GTFS." + upload fallback |
| Catalog id not found | "We couldn't find feed [id] in [catalog]." + paste-URL fallback |
| File exceeds 100 MB | "This feed is larger than our 100 MB import limit." + contact |
| URL points at a private network | Hard reject (SSRF protection — blocks 10/8, 172.16/12, 192.168/16, 127/8, 169.254/16, and IPv6 literals). |
Rate limits and reliability
- Rate limit: 30 imports per hour per IP. If a partner expects burst usage above this, get in touch — we can lift it per-domain.
- Size limit: 100 MB compressed (enforced via streaming;
Content-Lengthheaders can lie, so the cap holds even when servers misreport). - Redirect cap: 5 hops, SSRF check at each.
- Timeout: 30 s total for fetch + parse.
- Target uptime: matches the editor itself — Cloudflare-hosted, p99 < 200 ms worldwide for a cached fetch path.
Partner attribution
A "Loaded from <partner>" banner appears in the editor after the import completes. It shows automatically for catalog-source imports: any link using source=mobilitydb renders "Loaded from Mobility Database" with no extra parameters needed.
For url-based imports (?url=...), pass ref=<your-name> to trigger the banner and to show up in our analytics dashboard. Currently recognised ref values: mobilitydb, transitland, gtfs_validator. Get in touch to add yours.
The banner is dismissible and session-scoped -- it disappears after the user closes it or ends the browser tab.
See also
Once an edited feed is ready to publish, see How to publish a GTFS feed for the end-to-end workflow — Mobility Database registration, hosted-URL options, validation, and what tends to break.
Contact
Mark Egge — mark@gtfsx.com. Happy to whitelist partner domains for higher rate limits, register additional ref tags for attribution badges, or pair on integration design.