> ## Documentation Index
> Fetch the complete documentation index at: https://docs.beta.b3os.org/llms.txt
> Use this file to discover all available pages before exploring further.

# GitHub App callback

Where GitHub sends the browser after an install (the App's setup and callback URL). A signed-out browser is sent to sign in and then back here with `installation_id`. Without a code, or with a code but no state this edge issued for the current session, it asks GitHub to authorize the App once more with a state bound to the session. With both, it exchanges the code for the App's user access token and checks that `GET /user/installations` lists `installation_id` and that the GitHub account administers the installation's account: it is that user account, or an active owner of that organization (`GET /user/memberships/orgs/{org}`). Seeing the installation is not enough, since GitHub lists it to anyone who can read one of its repositories. Then it connects the installation to the organization, taking it over from another organization if one held it, and drops the token (it is never stored). It redirects to `redirect_to` with `github=connected`, or with `github_error=<reason>`. 

` GET /v1/github/callback `

GitHub App callback

Where GitHub sends the browser after an install (the App's setup and callback URL). A signed-out browser is
sent to sign in and then back here with `installation_id`. Without a code, or with a code but no state this
edge issued for the current session, it asks GitHub to authorize the App once more with a state bound to the
session. With both, it exchanges the code for the App's user access token and checks that
`GET /user/installations` lists `installation_id` and that the GitHub account administers the installation's
account: it is that user account, or an active owner of that organization
(`GET /user/memberships/orgs/{org}`). Seeing the installation is not enough, since GitHub lists it to anyone
who can read one of its repositories. Then it connects the installation to the organization, taking it
over from another organization if one held it, and drops the token (it is never stored). It redirects to
`redirect_to` with `github=connected`, or with `github_error=<reason>`.


## Servers

- ` https://beta.b3os.org `

## Parameters

### ` code ` (query, optional)

- ` value `: type ` string `

  - maxLength: ` 512 `

### ` state ` (query, optional)

- ` value `: type ` string `

  - maxLength: ` 512 `

### ` installation_id ` (query, optional)

- ` value `: type ` string `

  - pattern: ` "^[1-9][0-9]{0,15}$" `

### ` setup_action ` (query, optional)

- ` value `: type ` string `

  - maxLength: ` 32 `

## Responses

### ` 302 ` — Connected (or failed); redirect to the dashboard, or to GitHub to authorize first.

Response header ` x-request-id ` — The request ID (`req_…`). It is the `instance` of any problem and the key for `GET /v1/requests/{request_id}`.

- ` value `: type ` string `

  - pattern: ` "^req_[0-9a-hjkmnp-tv-z]{26}$" `

Response header ` Server-Timing ` — Phase durations in milliseconds (W3C Server Timing); the handler's phases break the request down. For a
response whose body size is known, `total` runs from reading the request head to writing the response head.
Streaming responses (event streams, WebSockets, chunked bodies) carry no `total` here: they report their
final phases in the terminal event (`job.succeeded`, `job.failed`, `job.canceled`) or the final job. The
time from the first request byte to the last response byte is recorded in the node's metrics and request
log (`GET /v1/requests/{request_id}`). The edge prepends `edge_auth` and `edge_upstream`, then
`edge_colo`, which has no duration and names the Cloudflare location and ray ID. The `desc` of `edge_auth`
names the steps it waited on as `<step>=<source>:<ms>`: `key` (`isolate`, `colo` or `primary`), `limits`
(`key` when they came with the key's read, `cache` or `d1`) and `permit` (`lease` or `limiter`, or
`optimistic` when the call went ahead and was counted right after). They are time inside `edge_auth`, not
added to it.


- ` value `: type ` string `

Response header ` Location ` — Where the browser goes next.

- ` value `: type ` string `

### ` 400 ` — The request failed validation (`invalid_request`, `invalid_url`).

Content type: ` application/problem+json `

- ` value `: type ` object ` — An RFC 9457 problem. `code` is stable and listed in the errors catalog; `type` links to its entry. `detail` is human-readable and may change. Extension members appear only for the codes that document them; ignore members you do not recognize. 

  - Required fields: ` type `, ` title `, ` status `, ` code `, ` detail `

  - ` type `: type ` string `; format ` uri ` — `https://docs.beta.b3os.org/errors#<code>`.

    - example: ` "https://docs.beta.b3os.org/errors#invalid_request" `

  - ` title `: type ` string ` — Short summary of the problem type.

  - ` status `: type ` integer ` — The HTTP status code, repeated for convenience.

    - minimum: ` 400 `

    - maximum: ` 599 `

  - ` code `: type ` string ` — Stable machine-readable error code from the errors catalog.

    - pattern: ` "^[a-z][a-z0-9_]*$" `

  - ` detail `: type ` string ` — Explanation of this occurrence. Never contains secrets.

  - ` instance `: type ` string ` — The request ID (`req_…`) of the request that failed. Include it when you contact support.

    - example: ` "req_01m5t4yg394wegr3j4y01qb363" `

  - ` errors `: type ` array ` — Validation problems, one per field (`invalid_request` and the other codes that list `errors`).

    - ` array item `: type ` object ` — One validation problem.

      - Required fields: ` pointer `, ` detail `

      - ` pointer `: type ` string ` — Where the problem is: a JSON pointer into the request body (`/url`, `/steps/0/uses`), or `#query/<name>`, `#path/<name>` or `#header/<name>` for parameters. 

        - example: ` "/url" `

      - ` detail `: type ` string ` — What is wrong there.

        - example: ` "must be an absolute http or https URL" `

  - ` reason `: type ` string ` — Finer-grained cause for codes that document one (`unauthorized`, `forbidden`, `egress_denied`, `upstream_unreachable`, …).

  - ` required_scope `: type ` string ` — The scope that was missing (`forbidden` with `reason: scope`).

  - ` retry_after_s `: type ` integer ` — Same value as the `Retry-After` header, for clients that only read the body.

    - minimum: ` 0 `

  - ` limit `: type ` object ` — The limit an error refers to. IDs and current values are listed by `GET /v1/limits`.

    - Required fields: ` id `, ` limit `, ` unit `

    - ` id `: type ` string ` — Limit ID, such as `vision.scrape.rpm` or `sandboxes.concurrent`.

      - example: ` "vision.scrape.rpm" `

    - ` limit `: type ` number ` — The limit's value.

    - ` unit `: type ` string ` — What the limit counts, such as `requests`, `sandboxes`, `vcpu` or `MiB`.

    - ` window_s `: type ` integer ` — Window length in seconds for rate limits and quotas.

    - ` current `: type ` number ` — Current usage against the limit, when known.

  - ` current_status `: type ` string ` — The object's current status, for state conflicts such as `sandbox_not_running`.

  - ` upstream_status `: type ` integer ` — The HTTP status the upstream returned (`upstream_error`, `action_output_invalid`).

  - ` step `: type ` string ` — The failed step, as a step ID (routines), an index (`act`) or a path such as `beats/2/do/0` (render).

  - ` pack_error `: type ` object ` — The error a pack's error mapping chose (`upstream_error` from pack actions).

    - Required fields: ` code `, ` message `, ` retryable `

    - ` code `: type ` string `

    - ` message `: type ` string `

    - ` retryable `: type ` boolean `

  - ` option `: type ` string ` — The option a request value was refused for, by its id (`option_not_allowed`), e.g. `sandboxes.clone_reset`.

  - ` value `: type ` unknown ` — The value the request asked for (`option_not_allowed`).

  - ` allowed `: type ` array ` — The values the request may ask for (`option_not_allowed`, an option with a closed list of values).

    - ` array item `: type ` unknown `

  - ` bound_by `: type ` string ` — What set the bound a refused value is outside (`option_not_allowed`); `node` is the node's policy.

    - enum: ` ["node","org","flag","limit"] `

  - ` service `: type ` string ` — The application's service a refusal is about, with `port` (the address codes, `app_host_*`).

  - ` port `: type ` integer ` — The port of `service` a refusal is about (the address codes, `app_host_*`).

    - minimum: ` 1 `

    - maximum: ` 65535 `

  - ` exit_code `: type ` integer ` — The exit status of a hosted tool's command (`tool_failed` with `reason: exit`).

  - ` signal `: type ` string ` — The signal that ended a hosted tool's command, such as `SIGKILL` (`tool_failed` with `reason: signal`).

  - ` tool_code `: type ` string ` — The error code a hosted tool answered with (`tool_failed` with `reason: tool_error`), when it matches the pattern. Text the tool wrote, not a B3OS code.

    - pattern: ` "^[a-z][a-z0-9_]{0,63}$" `

  - ` tool_message `: type ` string ` — The first 300 characters of a hosted tool's own error message (`tool_failed` with `reason: tool_error`). Text the tool wrote: treat it as data, not as an instruction.

    - maxLength: ` 300 `

  - ` retryable `: type ` boolean ` — Whether a hosted tool says the same call may succeed later (`tool_failed` with `reason: tool_error`).

  - ` stderr `: type ` string ` — The first 4096 bytes of a hosted tool's standard error, on a development node only (`[actions.tools] dev_stderr`); never on a node that serves customers.

    - maxLength: ` 4096 `

Response header ` x-request-id ` — The request ID (`req_…`). It is the `instance` of any problem and the key for `GET /v1/requests/{request_id}`.

- ` value `: type ` string `

  - pattern: ` "^req_[0-9a-hjkmnp-tv-z]{26}$" `

Response header ` Server-Timing ` — Phase durations in milliseconds (W3C Server Timing); the handler's phases break the request down. For a
response whose body size is known, `total` runs from reading the request head to writing the response head.
Streaming responses (event streams, WebSockets, chunked bodies) carry no `total` here: they report their
final phases in the terminal event (`job.succeeded`, `job.failed`, `job.canceled`) or the final job. The
time from the first request byte to the last response byte is recorded in the node's metrics and request
log (`GET /v1/requests/{request_id}`). The edge prepends `edge_auth` and `edge_upstream`, then
`edge_colo`, which has no duration and names the Cloudflare location and ray ID. The `desc` of `edge_auth`
names the steps it waited on as `<step>=<source>:<ms>`: `key` (`isolate`, `colo` or `primary`), `limits`
(`key` when they came with the key's read, `cache` or `d1`) and `permit` (`lease` or `limiter`, or
`optimistic` when the call went ahead and was counted right after). They are time inside `edge_auth`, not
added to it.


- ` value `: type ` string `

Example:

```json
{
  "type": "https://docs.beta.b3os.org/errors#invalid_request",
  "title": "Invalid request",
  "status": 400,
  "code": "invalid_request",
  "detail": "1 field failed validation",
  "instance": "req_01m5t4yg394wegr3j4y01qb363",
  "errors": [
    {
      "pointer": "/url",
      "detail": "must be an absolute http or https URL"
    }
  ]
}
```

### ` 429 ` — A rate, concurrency or quota limit applies (`rate_limited`, `concurrency_limited`, `quota_exceeded`).

Content type: ` application/problem+json `

- ` value `: type ` object ` — An RFC 9457 problem. `code` is stable and listed in the errors catalog; `type` links to its entry. `detail` is human-readable and may change. Extension members appear only for the codes that document them; ignore members you do not recognize. 

  - Required fields: ` type `, ` title `, ` status `, ` code `, ` detail `

  - ` type `: type ` string `; format ` uri ` — `https://docs.beta.b3os.org/errors#<code>`.

    - example: ` "https://docs.beta.b3os.org/errors#invalid_request" `

  - ` title `: type ` string ` — Short summary of the problem type.

  - ` status `: type ` integer ` — The HTTP status code, repeated for convenience.

    - minimum: ` 400 `

    - maximum: ` 599 `

  - ` code `: type ` string ` — Stable machine-readable error code from the errors catalog.

    - pattern: ` "^[a-z][a-z0-9_]*$" `

  - ` detail `: type ` string ` — Explanation of this occurrence. Never contains secrets.

  - ` instance `: type ` string ` — The request ID (`req_…`) of the request that failed. Include it when you contact support.

    - example: ` "req_01m5t4yg394wegr3j4y01qb363" `

  - ` errors `: type ` array ` — Validation problems, one per field (`invalid_request` and the other codes that list `errors`).

    - ` array item `: type ` object ` — One validation problem.

      - Required fields: ` pointer `, ` detail `

      - ` pointer `: type ` string ` — Where the problem is: a JSON pointer into the request body (`/url`, `/steps/0/uses`), or `#query/<name>`, `#path/<name>` or `#header/<name>` for parameters. 

        - example: ` "/url" `

      - ` detail `: type ` string ` — What is wrong there.

        - example: ` "must be an absolute http or https URL" `

  - ` reason `: type ` string ` — Finer-grained cause for codes that document one (`unauthorized`, `forbidden`, `egress_denied`, `upstream_unreachable`, …).

  - ` required_scope `: type ` string ` — The scope that was missing (`forbidden` with `reason: scope`).

  - ` retry_after_s `: type ` integer ` — Same value as the `Retry-After` header, for clients that only read the body.

    - minimum: ` 0 `

  - ` limit `: type ` object ` — The limit an error refers to. IDs and current values are listed by `GET /v1/limits`.

    - Required fields: ` id `, ` limit `, ` unit `

    - ` id `: type ` string ` — Limit ID, such as `vision.scrape.rpm` or `sandboxes.concurrent`.

      - example: ` "vision.scrape.rpm" `

    - ` limit `: type ` number ` — The limit's value.

    - ` unit `: type ` string ` — What the limit counts, such as `requests`, `sandboxes`, `vcpu` or `MiB`.

    - ` window_s `: type ` integer ` — Window length in seconds for rate limits and quotas.

    - ` current `: type ` number ` — Current usage against the limit, when known.

  - ` current_status `: type ` string ` — The object's current status, for state conflicts such as `sandbox_not_running`.

  - ` upstream_status `: type ` integer ` — The HTTP status the upstream returned (`upstream_error`, `action_output_invalid`).

  - ` step `: type ` string ` — The failed step, as a step ID (routines), an index (`act`) or a path such as `beats/2/do/0` (render).

  - ` pack_error `: type ` object ` — The error a pack's error mapping chose (`upstream_error` from pack actions).

    - Required fields: ` code `, ` message `, ` retryable `

    - ` code `: type ` string `

    - ` message `: type ` string `

    - ` retryable `: type ` boolean `

  - ` option `: type ` string ` — The option a request value was refused for, by its id (`option_not_allowed`), e.g. `sandboxes.clone_reset`.

  - ` value `: type ` unknown ` — The value the request asked for (`option_not_allowed`).

  - ` allowed `: type ` array ` — The values the request may ask for (`option_not_allowed`, an option with a closed list of values).

    - ` array item `: type ` unknown `

  - ` bound_by `: type ` string ` — What set the bound a refused value is outside (`option_not_allowed`); `node` is the node's policy.

    - enum: ` ["node","org","flag","limit"] `

  - ` service `: type ` string ` — The application's service a refusal is about, with `port` (the address codes, `app_host_*`).

  - ` port `: type ` integer ` — The port of `service` a refusal is about (the address codes, `app_host_*`).

    - minimum: ` 1 `

    - maximum: ` 65535 `

  - ` exit_code `: type ` integer ` — The exit status of a hosted tool's command (`tool_failed` with `reason: exit`).

  - ` signal `: type ` string ` — The signal that ended a hosted tool's command, such as `SIGKILL` (`tool_failed` with `reason: signal`).

  - ` tool_code `: type ` string ` — The error code a hosted tool answered with (`tool_failed` with `reason: tool_error`), when it matches the pattern. Text the tool wrote, not a B3OS code.

    - pattern: ` "^[a-z][a-z0-9_]{0,63}$" `

  - ` tool_message `: type ` string ` — The first 300 characters of a hosted tool's own error message (`tool_failed` with `reason: tool_error`). Text the tool wrote: treat it as data, not as an instruction.

    - maxLength: ` 300 `

  - ` retryable `: type ` boolean ` — Whether a hosted tool says the same call may succeed later (`tool_failed` with `reason: tool_error`).

  - ` stderr `: type ` string ` — The first 4096 bytes of a hosted tool's standard error, on a development node only (`[actions.tools] dev_stderr`); never on a node that serves customers.

    - maxLength: ` 4096 `

Response header ` x-request-id ` — The request ID (`req_…`). It is the `instance` of any problem and the key for `GET /v1/requests/{request_id}`.

- ` value `: type ` string `

  - pattern: ` "^req_[0-9a-hjkmnp-tv-z]{26}$" `

Response header ` Server-Timing ` — Phase durations in milliseconds (W3C Server Timing); the handler's phases break the request down. For a
response whose body size is known, `total` runs from reading the request head to writing the response head.
Streaming responses (event streams, WebSockets, chunked bodies) carry no `total` here: they report their
final phases in the terminal event (`job.succeeded`, `job.failed`, `job.canceled`) or the final job. The
time from the first request byte to the last response byte is recorded in the node's metrics and request
log (`GET /v1/requests/{request_id}`). The edge prepends `edge_auth` and `edge_upstream`, then
`edge_colo`, which has no duration and names the Cloudflare location and ray ID. The `desc` of `edge_auth`
names the steps it waited on as `<step>=<source>:<ms>`: `key` (`isolate`, `colo` or `primary`), `limits`
(`key` when they came with the key's read, `cache` or `d1`) and `permit` (`lease` or `limiter`, or
`optimistic` when the call went ahead and was counted right after). They are time inside `edge_auth`, not
added to it.


- ` value `: type ` string `

Response header ` Retry-After ` — Seconds to wait before retrying or polling again.

- ` value `: type ` integer `

  - minimum: ` 0 `

Response header ` RateLimit-Limit ` — Requests allowed in the current window for the limit that applies to this operation.

- ` value `: type ` integer `

Response header ` RateLimit-Remaining ` — Requests left in the current window.

- ` value `: type ` integer `

Response header ` RateLimit-Reset ` — Seconds until the current window resets.

- ` value `: type ` integer `

Response header ` RateLimit-Policy ` — The applied policy as `<limit>;w=<window seconds>;name="<limit id>"` (limit IDs are listed by `GET /v1/limits`).

- ` value `: type ` string `

Example:

```json
{
  "type": "https://docs.beta.b3os.org/errors#rate_limited",
  "title": "Rate limited",
  "status": 429,
  "code": "rate_limited",
  "detail": "60 scrapes per minute allowed; retry in 12 seconds",
  "instance": "req_01m5t4yg394wegr3j4y01qb363",
  "retry_after_s": 12,
  "limit": {
    "id": "vision.scrape.rpm",
    "limit": 60,
    "unit": "requests",
    "window_s": 60,
    "current": 60
  }
}
```

### ` 500 ` — Something failed inside B3OS (`internal`). Retry with backoff.

Content type: ` application/problem+json `

- ` value `: type ` object ` — An RFC 9457 problem. `code` is stable and listed in the errors catalog; `type` links to its entry. `detail` is human-readable and may change. Extension members appear only for the codes that document them; ignore members you do not recognize. 

  - Required fields: ` type `, ` title `, ` status `, ` code `, ` detail `

  - ` type `: type ` string `; format ` uri ` — `https://docs.beta.b3os.org/errors#<code>`.

    - example: ` "https://docs.beta.b3os.org/errors#invalid_request" `

  - ` title `: type ` string ` — Short summary of the problem type.

  - ` status `: type ` integer ` — The HTTP status code, repeated for convenience.

    - minimum: ` 400 `

    - maximum: ` 599 `

  - ` code `: type ` string ` — Stable machine-readable error code from the errors catalog.

    - pattern: ` "^[a-z][a-z0-9_]*$" `

  - ` detail `: type ` string ` — Explanation of this occurrence. Never contains secrets.

  - ` instance `: type ` string ` — The request ID (`req_…`) of the request that failed. Include it when you contact support.

    - example: ` "req_01m5t4yg394wegr3j4y01qb363" `

  - ` errors `: type ` array ` — Validation problems, one per field (`invalid_request` and the other codes that list `errors`).

    - ` array item `: type ` object ` — One validation problem.

      - Required fields: ` pointer `, ` detail `

      - ` pointer `: type ` string ` — Where the problem is: a JSON pointer into the request body (`/url`, `/steps/0/uses`), or `#query/<name>`, `#path/<name>` or `#header/<name>` for parameters. 

        - example: ` "/url" `

      - ` detail `: type ` string ` — What is wrong there.

        - example: ` "must be an absolute http or https URL" `

  - ` reason `: type ` string ` — Finer-grained cause for codes that document one (`unauthorized`, `forbidden`, `egress_denied`, `upstream_unreachable`, …).

  - ` required_scope `: type ` string ` — The scope that was missing (`forbidden` with `reason: scope`).

  - ` retry_after_s `: type ` integer ` — Same value as the `Retry-After` header, for clients that only read the body.

    - minimum: ` 0 `

  - ` limit `: type ` object ` — The limit an error refers to. IDs and current values are listed by `GET /v1/limits`.

    - Required fields: ` id `, ` limit `, ` unit `

    - ` id `: type ` string ` — Limit ID, such as `vision.scrape.rpm` or `sandboxes.concurrent`.

      - example: ` "vision.scrape.rpm" `

    - ` limit `: type ` number ` — The limit's value.

    - ` unit `: type ` string ` — What the limit counts, such as `requests`, `sandboxes`, `vcpu` or `MiB`.

    - ` window_s `: type ` integer ` — Window length in seconds for rate limits and quotas.

    - ` current `: type ` number ` — Current usage against the limit, when known.

  - ` current_status `: type ` string ` — The object's current status, for state conflicts such as `sandbox_not_running`.

  - ` upstream_status `: type ` integer ` — The HTTP status the upstream returned (`upstream_error`, `action_output_invalid`).

  - ` step `: type ` string ` — The failed step, as a step ID (routines), an index (`act`) or a path such as `beats/2/do/0` (render).

  - ` pack_error `: type ` object ` — The error a pack's error mapping chose (`upstream_error` from pack actions).

    - Required fields: ` code `, ` message `, ` retryable `

    - ` code `: type ` string `

    - ` message `: type ` string `

    - ` retryable `: type ` boolean `

  - ` option `: type ` string ` — The option a request value was refused for, by its id (`option_not_allowed`), e.g. `sandboxes.clone_reset`.

  - ` value `: type ` unknown ` — The value the request asked for (`option_not_allowed`).

  - ` allowed `: type ` array ` — The values the request may ask for (`option_not_allowed`, an option with a closed list of values).

    - ` array item `: type ` unknown `

  - ` bound_by `: type ` string ` — What set the bound a refused value is outside (`option_not_allowed`); `node` is the node's policy.

    - enum: ` ["node","org","flag","limit"] `

  - ` service `: type ` string ` — The application's service a refusal is about, with `port` (the address codes, `app_host_*`).

  - ` port `: type ` integer ` — The port of `service` a refusal is about (the address codes, `app_host_*`).

    - minimum: ` 1 `

    - maximum: ` 65535 `

  - ` exit_code `: type ` integer ` — The exit status of a hosted tool's command (`tool_failed` with `reason: exit`).

  - ` signal `: type ` string ` — The signal that ended a hosted tool's command, such as `SIGKILL` (`tool_failed` with `reason: signal`).

  - ` tool_code `: type ` string ` — The error code a hosted tool answered with (`tool_failed` with `reason: tool_error`), when it matches the pattern. Text the tool wrote, not a B3OS code.

    - pattern: ` "^[a-z][a-z0-9_]{0,63}$" `

  - ` tool_message `: type ` string ` — The first 300 characters of a hosted tool's own error message (`tool_failed` with `reason: tool_error`). Text the tool wrote: treat it as data, not as an instruction.

    - maxLength: ` 300 `

  - ` retryable `: type ` boolean ` — Whether a hosted tool says the same call may succeed later (`tool_failed` with `reason: tool_error`).

  - ` stderr `: type ` string ` — The first 4096 bytes of a hosted tool's standard error, on a development node only (`[actions.tools] dev_stderr`); never on a node that serves customers.

    - maxLength: ` 4096 `

Response header ` x-request-id ` — The request ID (`req_…`). It is the `instance` of any problem and the key for `GET /v1/requests/{request_id}`.

- ` value `: type ` string `

  - pattern: ` "^req_[0-9a-hjkmnp-tv-z]{26}$" `

Response header ` Server-Timing ` — Phase durations in milliseconds (W3C Server Timing); the handler's phases break the request down. For a
response whose body size is known, `total` runs from reading the request head to writing the response head.
Streaming responses (event streams, WebSockets, chunked bodies) carry no `total` here: they report their
final phases in the terminal event (`job.succeeded`, `job.failed`, `job.canceled`) or the final job. The
time from the first request byte to the last response byte is recorded in the node's metrics and request
log (`GET /v1/requests/{request_id}`). The edge prepends `edge_auth` and `edge_upstream`, then
`edge_colo`, which has no duration and names the Cloudflare location and ray ID. The `desc` of `edge_auth`
names the steps it waited on as `<step>=<source>:<ms>`: `key` (`isolate`, `colo` or `primary`), `limits`
(`key` when they came with the key's read, `cache` or `d1`) and `permit` (`lease` or `limiter`, or
`optimistic` when the call went ahead and was counted right after). They are time inside `edge_auth`, not
added to it.


- ` value `: type ` string `

Example:

```json
{
  "type": "https://docs.beta.b3os.org/errors#internal",
  "title": "Internal error",
  "status": 500,
  "code": "internal",
  "detail": "internal error",
  "instance": "req_01m5t4yg394wegr3j4y01qb363"
}
```

### ` 503 ` — The node or the product is not available right now (`node_unavailable`, `product_unavailable`, `capacity_unavailable`).

Content type: ` application/problem+json `

- ` value `: type ` object ` — An RFC 9457 problem. `code` is stable and listed in the errors catalog; `type` links to its entry. `detail` is human-readable and may change. Extension members appear only for the codes that document them; ignore members you do not recognize. 

  - Required fields: ` type `, ` title `, ` status `, ` code `, ` detail `

  - ` type `: type ` string `; format ` uri ` — `https://docs.beta.b3os.org/errors#<code>`.

    - example: ` "https://docs.beta.b3os.org/errors#invalid_request" `

  - ` title `: type ` string ` — Short summary of the problem type.

  - ` status `: type ` integer ` — The HTTP status code, repeated for convenience.

    - minimum: ` 400 `

    - maximum: ` 599 `

  - ` code `: type ` string ` — Stable machine-readable error code from the errors catalog.

    - pattern: ` "^[a-z][a-z0-9_]*$" `

  - ` detail `: type ` string ` — Explanation of this occurrence. Never contains secrets.

  - ` instance `: type ` string ` — The request ID (`req_…`) of the request that failed. Include it when you contact support.

    - example: ` "req_01m5t4yg394wegr3j4y01qb363" `

  - ` errors `: type ` array ` — Validation problems, one per field (`invalid_request` and the other codes that list `errors`).

    - ` array item `: type ` object ` — One validation problem.

      - Required fields: ` pointer `, ` detail `

      - ` pointer `: type ` string ` — Where the problem is: a JSON pointer into the request body (`/url`, `/steps/0/uses`), or `#query/<name>`, `#path/<name>` or `#header/<name>` for parameters. 

        - example: ` "/url" `

      - ` detail `: type ` string ` — What is wrong there.

        - example: ` "must be an absolute http or https URL" `

  - ` reason `: type ` string ` — Finer-grained cause for codes that document one (`unauthorized`, `forbidden`, `egress_denied`, `upstream_unreachable`, …).

  - ` required_scope `: type ` string ` — The scope that was missing (`forbidden` with `reason: scope`).

  - ` retry_after_s `: type ` integer ` — Same value as the `Retry-After` header, for clients that only read the body.

    - minimum: ` 0 `

  - ` limit `: type ` object ` — The limit an error refers to. IDs and current values are listed by `GET /v1/limits`.

    - Required fields: ` id `, ` limit `, ` unit `

    - ` id `: type ` string ` — Limit ID, such as `vision.scrape.rpm` or `sandboxes.concurrent`.

      - example: ` "vision.scrape.rpm" `

    - ` limit `: type ` number ` — The limit's value.

    - ` unit `: type ` string ` — What the limit counts, such as `requests`, `sandboxes`, `vcpu` or `MiB`.

    - ` window_s `: type ` integer ` — Window length in seconds for rate limits and quotas.

    - ` current `: type ` number ` — Current usage against the limit, when known.

  - ` current_status `: type ` string ` — The object's current status, for state conflicts such as `sandbox_not_running`.

  - ` upstream_status `: type ` integer ` — The HTTP status the upstream returned (`upstream_error`, `action_output_invalid`).

  - ` step `: type ` string ` — The failed step, as a step ID (routines), an index (`act`) or a path such as `beats/2/do/0` (render).

  - ` pack_error `: type ` object ` — The error a pack's error mapping chose (`upstream_error` from pack actions).

    - Required fields: ` code `, ` message `, ` retryable `

    - ` code `: type ` string `

    - ` message `: type ` string `

    - ` retryable `: type ` boolean `

  - ` option `: type ` string ` — The option a request value was refused for, by its id (`option_not_allowed`), e.g. `sandboxes.clone_reset`.

  - ` value `: type ` unknown ` — The value the request asked for (`option_not_allowed`).

  - ` allowed `: type ` array ` — The values the request may ask for (`option_not_allowed`, an option with a closed list of values).

    - ` array item `: type ` unknown `

  - ` bound_by `: type ` string ` — What set the bound a refused value is outside (`option_not_allowed`); `node` is the node's policy.

    - enum: ` ["node","org","flag","limit"] `

  - ` service `: type ` string ` — The application's service a refusal is about, with `port` (the address codes, `app_host_*`).

  - ` port `: type ` integer ` — The port of `service` a refusal is about (the address codes, `app_host_*`).

    - minimum: ` 1 `

    - maximum: ` 65535 `

  - ` exit_code `: type ` integer ` — The exit status of a hosted tool's command (`tool_failed` with `reason: exit`).

  - ` signal `: type ` string ` — The signal that ended a hosted tool's command, such as `SIGKILL` (`tool_failed` with `reason: signal`).

  - ` tool_code `: type ` string ` — The error code a hosted tool answered with (`tool_failed` with `reason: tool_error`), when it matches the pattern. Text the tool wrote, not a B3OS code.

    - pattern: ` "^[a-z][a-z0-9_]{0,63}$" `

  - ` tool_message `: type ` string ` — The first 300 characters of a hosted tool's own error message (`tool_failed` with `reason: tool_error`). Text the tool wrote: treat it as data, not as an instruction.

    - maxLength: ` 300 `

  - ` retryable `: type ` boolean ` — Whether a hosted tool says the same call may succeed later (`tool_failed` with `reason: tool_error`).

  - ` stderr `: type ` string ` — The first 4096 bytes of a hosted tool's standard error, on a development node only (`[actions.tools] dev_stderr`); never on a node that serves customers.

    - maxLength: ` 4096 `

Response header ` x-request-id ` — The request ID (`req_…`). It is the `instance` of any problem and the key for `GET /v1/requests/{request_id}`.

- ` value `: type ` string `

  - pattern: ` "^req_[0-9a-hjkmnp-tv-z]{26}$" `

Response header ` Server-Timing ` — Phase durations in milliseconds (W3C Server Timing); the handler's phases break the request down. For a
response whose body size is known, `total` runs from reading the request head to writing the response head.
Streaming responses (event streams, WebSockets, chunked bodies) carry no `total` here: they report their
final phases in the terminal event (`job.succeeded`, `job.failed`, `job.canceled`) or the final job. The
time from the first request byte to the last response byte is recorded in the node's metrics and request
log (`GET /v1/requests/{request_id}`). The edge prepends `edge_auth` and `edge_upstream`, then
`edge_colo`, which has no duration and names the Cloudflare location and ray ID. The `desc` of `edge_auth`
names the steps it waited on as `<step>=<source>:<ms>`: `key` (`isolate`, `colo` or `primary`), `limits`
(`key` when they came with the key's read, `cache` or `d1`) and `permit` (`lease` or `limiter`, or
`optimistic` when the call went ahead and was counted right after). They are time inside `edge_auth`, not
added to it.


- ` value `: type ` string `

Response header ` Retry-After ` — Seconds to wait before retrying or polling again.

- ` value `: type ` integer `

  - minimum: ` 0 `

Example:

```json
{
  "type": "https://docs.beta.b3os.org/errors#node_unavailable",
  "title": "Node unavailable",
  "status": 503,
  "code": "node_unavailable",
  "detail": "Node n1 is not reachable; retry in 5 seconds",
  "instance": "req_01m5t4yg394wegr3j4y01qb363",
  "retry_after_s": 5
}
```

## Request examples

### cURL

```curl
curl -X GET 'https://beta.b3os.org/v1/github/callback' \
  -H 'Authorization: Bearer YOUR_API_TOKEN'
```

### JavaScript

```javascript
const response = await fetch('https://beta.b3os.org/v1/github/callback', {
  method: 'GET',
  headers: {
      "Authorization": "Bearer YOUR_API_TOKEN"
  }
});

const data = await response.json();
console.log(data);
```

### Python

```python
import requests

headers = {
    'Authorization': 'Bearer YOUR_API_TOKEN'
}

response = requests.get('https://beta.b3os.org/v1/github/callback', headers=headers)
print(response.json())
```