til: fly_undocumented-graphql-api.md
This data as json
| path | topic | title | url | body | html | shot | created | created_utc | updated | updated_utc | shot_hash | slug |
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| fly_undocumented-graphql-api.md | fly | Using the undocumented Fly GraphQL API | https://github.com/simonw/til/blob/main/fly/undocumented-graphql-api.md | [Fly](https://fly.io/) has a GraphQL API which is used by some of their own tools - I found it while [browsing around their code](https://github.com/superfly/flyctl/blob/603b0adccf5416188eabaa7dc73f9c0ec88fa6ca/api/resource_volumes.go#L5-L40) on GitHub. It's very much undocumented, which means you would be very foolish to write any software against it and expect it to continue to work as Fly make changes. Only it is *kind of* documented, because GraphQL introspection provides decent documentation. (Also it's used [by example code](https://github.com/fly-apps/hostnamesapi) published by Fly, so maybe it's more supported than I initially thought.) The endpoint is `https://api.fly.io/graphql` - you need a `Authorization: Bearer xxx` HTTP header to access it, where you can get the `xxx` token by running `flyctl auth token`. Or, you can point your browser directly at https://api.fly.io/graphql - they are running a copy of [GraphiQL](https://github.com/graphql/graphiql) there which provides an interactive explorer plus documentation and schema tabs. And if you're signed in to the Fly web interface it will use your `.fly.io` cookies to authenticate your GraphQL requests - so no need to worry about that `Authorization` header. Here's a query I used to answer the question "what volumes do I have attached, across all of my instances?" ```graphql { apps { nodes { name volumes { nodes { name } } } } } ``` Here's a much more fun query: ```graphql { # Your user account: viewer { avatarUrl createdAt email # This returned the following for me: # ["backend_wordpress", "response_headers_middleware", "firecracker", "dashboard_logs"] featureFlags } nearestRegion { # This returned "sjc" code } personalOrganization { name creditBalance creditBalanceFormatted # Not sure what these are but they look interesting - I have 7 loggedCertificates { totalCount nodes { cert id root } } isCreditCardSaved wireGuardPeers { # Returned one entry for me, with name: # interactive-Simons-MacBook-Pro-swillison-gmail-com-26 # Presumably the flyctl CLI command set this up totalCount nodes { name network peerip pubkey region } } } } ``` This one returns recent logs (only for the past hour / max of 50 values - those are the highest numbers that can be used for those parameters): ```graphql { apps { nodes { name vms { totalCount nodes { recentLogs(limit: 50, range: 3600) { id region message timestamp } } } } } } ``` And another one which digs into the details of attached volumes: ```graphql { apps { nodes { name services { checks { httpPath httpMethod name } description } volumes { nodes { id name createdAt host { id } sizeGb status usedBytes region app { name } attachedAllocation { privateIP # Not sure why attachedAllocation on a volume gives app HTTP traffic logs: recentLogs { id message timestamp } canary events { message timestamp } } } } } } } ``` | <p><a href="https://fly.io/" rel="nofollow">Fly</a> has a GraphQL API which is used by some of their own tools - I found it while <a href="https://github.com/superfly/flyctl/blob/603b0adccf5416188eabaa7dc73f9c0ec88fa6ca/api/resource_volumes.go#L5-L40">browsing around their code</a> on GitHub.</p> <p>It's very much undocumented, which means you would be very foolish to write any software against it and expect it to continue to work as Fly make changes.</p> <p>Only it is <em>kind of</em> documented, because GraphQL introspection provides decent documentation.</p> <p>(Also it's used <a href="https://github.com/fly-apps/hostnamesapi">by example code</a> published by Fly, so maybe it's more supported than I initially thought.)</p> <p>The endpoint is <code>https://api.fly.io/graphql</code> - you need a <code>Authorization: Bearer xxx</code> HTTP header to access it, where you can get the <code>xxx</code> token by running <code>flyctl auth token</code>.</p> <p>Or, you can point your browser directly at <a href="https://api.fly.io/graphql" rel="nofollow">https://api.fly.io/graphql</a> - they are running a copy of <a href="https://github.com/graphql/graphiql">GraphiQL</a> there which provides an interactive explorer plus documentation and schema tabs.</p> <p>And if you're signed in to the Fly web interface it will use your <code>.fly.io</code> cookies to authenticate your GraphQL requests - so no need to worry about that <code>Authorization</code> header.</p> <p>Here's a query I used to answer the question "what volumes do I have attached, across all of my instances?"</p> <div class="highlight highlight-source-graphql"><pre>{ <span class="pl-v">apps</span> { <span class="pl-v">nodes</span> { <span class="pl-v">name</span> <span class="pl-v">volumes</span> { <span class="pl-v">nodes</span> { <span class="pl-v">name</span> } } } } }</pre></div> <p>Here's a much more fun query:</p> <div class="highlight highlight-source-graphql"><pre>{ <span class="pl-c"> # Your user account:</span> <span class="pl-v">viewer</span> { <span class="pl-v">avatarUrl</span> <span class="pl-v">createdAt</span> <span class="pl-v">email</span> <span class="pl-c"> # This returned the following for me:</span> <span class="pl-c"> # ["backend_wordpress", "response_headers_middleware", "firecracker", "dashboard_logs"]</span> <span class="pl-v">featureFlags</span> } <span class="pl-v">nearestRegion</span> { <span class="pl-c"> # This returned "sjc"</span> <span class="pl-v">code</span> } <span class="pl-v">personalOrganization</span> { <span class="pl-v">name</span> <span class="pl-v">creditBalance</span> <span class="pl-v">creditBalanceFormatted</span> <span class="pl-c"> # Not sure what these are but they look interesting - I have 7</span> <span class="pl-v">loggedCertificates</span> { <span class="pl-v">totalCount</span> <span class="pl-v">nodes</span> { <span class="pl-v">cert</span> <span class="pl-v">id</span> <span class="pl-v">root</span> } } <span class="pl-v">isCreditCardSaved</span> <span class="pl-v">wireGuardPeers</span> { <span class="pl-c"> # Returned one entry for me, with name:</span> <span class="pl-c"> # interactive-Simons-MacBook-Pro-swillison-gmail-com-26</span> <span class="pl-c"> # Presumably the flyctl CLI command set this up</span> <span class="pl-v">totalCount</span> <span class="pl-v">nodes</span> { <span class="pl-v">name</span> <span class="pl-v">network</span> <span class="pl-v">peerip</span> <span class="pl-v">pubkey</span> <span class="pl-v">region</span> } } } }</pre></div> <p>This one returns recent logs (only for the past hour / max of 50 values - those are the highest numbers that can be used for those parameters):</p> <div class="highlight highlight-source-graphql"><pre>{ <span class="pl-v">apps</span> { <span class="pl-v">nodes</span> { <span class="pl-v">name</span> <span class="pl-v">vms</span> { <span class="pl-v">totalCount</span> <span class="pl-v">nodes</span> { <span class="pl-v">recentLogs</span>(<span class="pl-v">limit</span>: <span class="pl-c1">50</span>, <span class="pl-v">range</span>: <span class="pl-c1">3600</span>) { <span class="pl-v">id</span> <span class="pl-v">region</span> <span class="pl-v">message</span> <span class="pl-v">timestamp</span> } } } } } }</pre></div> <p>And another one which digs into the details of attached volumes:</p> <div class="highlight highlight-source-graphql"><pre>{ <span class="pl-v">apps</span> { <span class="pl-v">nodes</span> { <span class="pl-v">name</span> <span class="pl-v">services</span> { <span class="pl-v">checks</span> { <span class="pl-v">httpPath</span> <span class="pl-v">httpMethod</span> <span class="pl-v">name</span> } <span class="pl-v">description</span> } <span class="pl-v">volumes</span> { <span class="pl-v">nodes</span> { <span class="pl-v">id</span> <span class="pl-v">name</span> <span class="pl-v">createdAt</span> <span class="pl-v">host</span> { <span class="pl-v">id</span> } <span class="pl-v">sizeGb</span> <span class="pl-v">status</span> <span class="pl-v">usedBytes</span> <span class="pl-v">region</span> <span class="pl-v">app</span> { <span class="pl-v">name</span> } <span class="pl-v">attachedAllocation</span> { <span class="pl-v">privateIP</span> <span class="pl-c"> # Not sure why attachedAllocation on a volume gives app HTTP traffic logs:</span> <span class="pl-v">recentLogs</span> { <span class="pl-v">id</span> <span class="pl-v">message</span> <span class="pl-v">timestamp</span> } <span class="pl-v">canary</span> <span class="pl-v">events</span> { <span class="pl-v">message</span> <span class="pl-v">timestamp</span> } } } } } } }</pre></div> | <Binary: 89,644 bytes> | 2022-01-21T14:59:35-08:00 | 2022-01-21T22:59:35+00:00 | 2022-02-01T15:07:06-08:00 | 2022-02-01T23:07:06+00:00 | 74a5e0005a6e44d69b773fef0a2b0928 | undocumented-graphql-api |