# Get the runner bundle

> What a job's Claude Code loads from the workspace's Customize, read once per job with the job's agent token (or a workspace's token; a person's token is refused): plugins to fetch at their pinned commit (ref, name, fetch, version; switched-off ones left out), the library skills that reach the job's agent as files (each name with its files: path, content, encoding utf8 or base64; a plugin's skills come with the plugin), and the connectors that reach it and are connected, each with its name, url and the headers that sign it in.

<div class="g1t-endpoint"><span class="g1t-method" data-method="get">GET</span><code>/workspaces/{workspace}/customize/bundle</code></div>

Secrets are in it: it is for the runner, and g1t never keeps or logs it. See self-hosted runners, "What a run gets from Customize".

Read with the job's agent token: what comes back is what reaches that agent (its own grants, its teams' and the workspace's). A workspace's token gets everything the workspace has; a person's token is refused with `403`. `plugins` are switched-on installs, to fetch at `fetch.sha` (or `fetch.ref`); a plugin's skills are not repeated in `skills`, since Claude Code reads them from the plugin. `skills` are the library's own, as files for a synthetic plugin called `g1t-library`, so each is `/g1t-library:&lt;name>` in Claude Code. `connectors` are the connected ones that reach the agent, with the headers that sign them in, refreshed when a sign-in had expired: it is for the runner's `--mcp-config`, and g1t never keeps or logs it. See [what a run gets from Customize](/guides/self-hosted-runners/#what-a-run-gets-from-customize).

- **Authentication:** Required. Send an [access token](/reference/api/#authentication) as `Authorization: Bearer`.
- **MCP tool:** [`customize`](/reference/mcp/#customize) with `action` `bundle`, and the same inputs
- **Scope:** An access token needs [`agents:run`](/guides/authentication/#scopes).

## Path parameters

| Name | Type | Required | Description |
| --- | --- | --- | --- |
| `workspace` | string | Yes | The workspace's slug. |

## Example request

```sh
curl https://api.g1t.sh/workspaces/flagon-io/customize/bundle \
  -H "Authorization: Bearer $G1T_TOKEN"
```

## Example response

A successful request answers `200` with:

```json
{
  "plugins": [
    {
      "ref": "commit-commands@claude-plugins-official",
      "name": "commit-commands",
      "fetch": {
        "kind": "github",
        "repo": "anthropics/claude-plugins-official",
        "ref": null,
        "sha": "9c1f4a6e8b0d2c4f6a8e1b3d5f7a9c1e3b5d7f90",
        "path": "plugins/commit-commands"
      },
      "version": "1.0.0"
    }
  ],
  "skills": [
    {
      "name": "house-style",
      "plugin": null,
      "files": [
        {
          "path": "SKILL.md",
          "content": "---\nname: house-style\ndescription: How Flagon writes code and prose.\n---\n\n# House style\n…",
          "encoding": "utf8"
        },
        {
          "path": "examples/commit.md",
          "content": "# A good commit message\n…",
          "encoding": "utf8"
        }
      ]
    }
  ],
  "connectors": [
    {
      "name": "linear",
      "url": "https://mcp.linear.app/mcp",
      "headers": {
        "Authorization": "Bearer lin_oauth_…"
      }
    }
  ]
}
```

## Errors

A failed request answers with one of these statuses and a body like `{"error": {"code": "not_found", "message": "Repository not found."}}`. See [errors](/reference/api/#errors).

| Status | Code | When |
| --- | --- | --- |
| 401 | `unauthenticated` | A token is required, or the one sent is not valid. |
| 403 | `forbidden` | The token is valid but not allowed to do this, such as a member-only change or an agent token outside its repository. |
| 404 | `not_found` | It does not exist, or you cannot see it. |
| 422 | `invalid` | The input is not valid. `message` says which field and why. |
