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

# Migrate from SDK versions 0.x

> Migrate Python, TypeScript, and Go code from Ona SDK versions 0.x to versions 1.x.

<Note>Available on the Enterprise plan. [Contact sales](https://ona.com/contact/sales) to learn more.</Note>

Upgrade the SDK package and update your code in the same change. SDK versions 1.x are not drop-in compatible with versions 0.x. The migration does not change Ona resources or invalidate personal access tokens.

If your application pins a 0.x version, migrate its code before upgrading the SDK dependency to 1.x.

The distribution names remain `gitpod-sdk`, `@gitpod/sdk`, and `github.com/gitpod-io/gitpod-sdk-go`. Imports, environment variables, request types, responses, and error types change.

Use the examples shipped in the [Python source distribution](https://pypi.org/project/gitpod-sdk/#files), [TypeScript package](https://unpkg.com/browse/@gitpod/sdk@latest/examples/), or [public Go module mirror](https://github.com/gitpod-io/gitpod-sdk-go). Do not use examples from the former language-specific SDK repositories.

## Review the breaking changes

| Concern                     | Versions 0.x                                                       | Versions 1.x                                                        |
| --------------------------- | ------------------------------------------------------------------ | ------------------------------------------------------------------- |
| API key variable            | `GITPOD_API_KEY`                                                   | `ONA_API_KEY`                                                       |
| Custom API URL              | Client-specific base URL option                                    | `ONA_BASE_URL` or a constructor option                              |
| Python client               | `Gitpod` or `AsyncGitpod` from `gitpod`                            | `create_client_from_env` or `create_client` from `ona_sdk`          |
| TypeScript client           | Default `Gitpod` export                                            | Named `createClientFromEnv`, `createClient`, or `OnaClient` exports |
| Go client                   | `gitpod.NewClient` and `option.*`                                  | `sdk.NewFromEnv` and `sdk.*` options                                |
| Request and response models | JSON models                                                        | Protobuf messages and Connect clients                               |
| Environment operations      | Service methods plus language-specific helpers                     | Resource clients and `Environment` handles                          |
| Python concurrency          | Synchronous and asynchronous clients                               | Synchronous client                                                  |
| Runtime                     | Python 3.9+, browser and server/edge JavaScript runtimes, Go 1.22+ | Python 3.10+, Node.js 20+, Go 1.25+                                 |
| Retries                     | Automatic retries for selected failures                            | No automatic application-level retries                              |
| Errors                      | 0.x API error hierarchy                                            | SDK workflow errors or Connect errors for direct RPCs               |

## Find SDK 0.x usage

Search the application before changing dependencies:

```bash theme={null}
rg -n 'GITPOD_API_KEY|from gitpod import|AsyncGitpod|new Gitpod|gitpod.NewClient|gitpod-sdk-go/option'
```

Also inspect wrapper modules, dependency lockfiles, deployment secrets, retry configuration, and tests that mock 0.x response or error types. Keep this list as the migration checklist for the application.

## Upgrade the package

Upgrade the package and commit the resulting lockfile or module changes:

<Tabs>
  <Tab title="Python">
    ```bash theme={null}
    python -m pip install --upgrade gitpod-sdk
    ```
  </Tab>

  <Tab title="TypeScript">
    ```bash theme={null}
    npm install @gitpod/sdk@latest
    ```
  </Tab>

  <Tab title="Go">
    ```bash theme={null}
    go get github.com/gitpod-io/gitpod-sdk-go@latest
    go mod tidy
    ```
  </Tab>
</Tabs>

Do not upgrade a production dependency before the matching code changes are ready. The new release replaces classes and types under the existing distribution names.

## Rename authentication variables

Rename `GITPOD_API_KEY` to `ONA_API_KEY` in deployment configuration, local environment files, and secret stores:

```bash theme={null}
export ONA_API_KEY="<personal-access-token>"
```

During a staged rollout, you can expose the same personal access token under both names. Remove `GITPOD_API_KEY` after every workload uses an SDK version 1.x.

For an organization with a custom management-plane domain, set the API URL explicitly:

```bash theme={null}
export ONA_BASE_URL="https://<custom-domain>/api"
```

The default is `https://app.ona.com/api`.

## Replace client construction and environment workflows

Move environment lifecycle and environment operations to the high-level resource clients. These workflows replace manual environment-class selection, polling helpers, and command helpers used with SDK versions 0.x.

<Tabs>
  <Tab title="Python">
    Replace `Gitpod` or `AsyncGitpod` with `create_client_from_env`:

    ```python theme={null}
    # Before: SDK 0.x
    from gitpod import Gitpod

    client = Gitpod()
    environments = client.environments.list()
    ```

    ```python theme={null}
    # After: SDK 1.x
    from ona_sdk import create_client_from_env

    ona = create_client_from_env()
    environments = ona.environments().list()
    ```

    Create an environment and run a command through the returned handle:

    ```python theme={null}
    environment = ona.environments().create(
        "https://github.com/gitpod-io/template-golang-cli"
    )

    try:
        result = environment.run_command(
            command="go test ./...",
            working_directory=environment.workspace_dir(),
        )
        print(result.stdout)
    finally:
        ona.environments().delete(environment.id(), force=True)
    ```

    The Python SDK version 1.x is synchronous. In an asynchronous application, call it through a worker thread instead of importing `AsyncGitpod`:

    ```python theme={null}
    import asyncio

    environment = await asyncio.to_thread(
        ona.environments().get,
        "<environment-id>",
    )
    ```
  </Tab>

  <Tab title="TypeScript">
    Replace the default `Gitpod` class with a named client factory:

    ```typescript theme={null}
    // Before: SDK 0.x
    import Gitpod from "@gitpod/sdk";

    const client = new Gitpod();
    const environments = client.environments.list();
    ```

    ```typescript theme={null}
    // After: SDK 1.x
    import { createClientFromEnv } from "@gitpod/sdk";

    const ona = createClientFromEnv();
    const environments = ona.environments().list();
    ```

    Create an environment and run a command through the returned handle:

    ```typescript theme={null}
    const environment = await ona.environments().create({
      contextUrl: "https://github.com/gitpod-io/template-golang-cli",
    });

    try {
      const result = await environment.runCommand({
        command: "go test ./...",
        workingDirectory: environment.workspaceDir(),
      });
      console.log(result.stdout);
    } finally {
      await ona.environments().delete(environment.id(), { force: true });
    }
    ```
  </Tab>

  <Tab title="Go">
    Replace the 0.x root client and `option` package with the high-level `sdk` package:

    ```go theme={null}
    // Before: SDK 0.x
    client := gitpod.NewClient(
        option.WithBearerToken(os.Getenv("GITPOD_API_KEY")),
    )
    ```

    ```go theme={null}
    // After: SDK 1.x
    ona, err := sdk.NewFromEnv()
    if err != nil {
        return err
    }
    ```

    Create an environment and run a command through the returned handle:

    ```go theme={null}
    environment, err := ona.Environments().Create(ctx, sdk.CreateEnvironmentOptions{
        ContextURL: "https://github.com/gitpod-io/template-golang-cli",
    })
    if err != nil {
        return err
    }
    defer ona.Environments().Delete(ctx, environment.ID(), sdk.DeleteEnvironmentOptions{Force: true})

    status := environment.Proto().GetStatus()
    workspaceDir := status.GetDevcontainer().GetRemoteWorkspaceFolder()
    if workspaceDir == "" {
        workspaceDir = status.GetContent().GetContentLocationInMachine()
    }

    result, err := environment.RunCommand(ctx, sdk.RunCommandOptions{
        Command:          "go test ./...",
        WorkingDirectory: workspaceDir,
    })
    if err != nil {
        return err
    }
    fmt.Print(result.Stdout)
    ```
  </Tab>
</Tabs>

High-level `create` calls wait for the environment to run. `stop` waits for the environment to stop, and `delete` cleans it up. Remove 0.x polling utilities that duplicate this behavior.

## Migrate direct API calls to Connect

Use generated protobuf messages and Connect clients for API methods that the high-level workflows do not cover. Request fields now follow the public protobuf schema instead of the parameter objects from versions 0.x.

<Tabs>
  <Tab title="Python">
    Authenticated synchronous service clients are available through `ona.services`:

    ```python theme={null}
    from gitpod.v1.identity_pb2 import GetAuthenticatedIdentityRequest
    from ona_sdk import create_client_from_env

    ona = create_client_from_env()
    response = ona.services.identity.get_authenticated_identity(
        GetAuthenticatedIdentityRequest()
    )
    print(response.organization_id)
    ```

    Generated responses are protobuf messages, not Pydantic models. Replace helpers such as `to_dict()` and `to_json()` with protobuf-aware serialization where needed.
  </Tab>

  <Tab title="TypeScript">
    Construct protobuf-es v2 messages with `create` and the generated request schema:

    ```typescript theme={null}
    import { create } from "@bufbuild/protobuf";
    import { createClientFromEnv } from "@gitpod/sdk";
    import { GetAuthenticatedIdentityRequestSchema } from "@gitpod/sdk/gitpod/v1/identity_pb";

    const ona = createClientFromEnv();
    const response = await ona.services.identity.getAuthenticatedIdentity(
      create(GetAuthenticatedIdentityRequestSchema),
    );
    console.log(response.organizationId);
    ```

    Import message types and service descriptors from generated package subpaths. Do not construct typed protobuf messages with bare object literals.
  </Tab>

  <Tab title="Go">
    Use the generated Connect clients under `v1/v1connect`. Configure the HTTP client with the same token used by the high-level SDK:

    ```go theme={null}
    token := os.Getenv("ONA_API_KEY")
    baseURL := os.Getenv("ONA_BASE_URL")
    if baseURL == "" {
        baseURL = "https://app.ona.com/api"
    }

    httpClient := oauth2.NewClient(ctx, oauth2.StaticTokenSource(
        &oauth2.Token{AccessToken: token},
    ))
    identity := v1connect.NewIdentityServiceClient(httpClient, baseURL)
    response, err := identity.GetAuthenticatedIdentity(
        ctx,
        connect.NewRequest(&v1.GetAuthenticatedIdentityRequest{}),
    )
    if err != nil {
        return err
    }
    fmt.Println(response.Msg.GetOrganizationId())
    ```

    This example uses `connectrpc.com/connect`, `golang.org/x/oauth2`, `github.com/gitpod-io/gitpod-sdk-go/v1`, and `github.com/gitpod-io/gitpod-sdk-go/v1/v1connect`.
  </Tab>
</Tabs>

See the [API reference](https://ona.com/docs/api-reference) for the current public services and fields.

## Update pagination, timeouts, and errors

Replace 0.x runtime helpers with their 1.x equivalents:

* **Pagination:** High-level environment lists still fetch pages lazily. Iterate the Python generator, TypeScript async generator, or Go `iter.Seq2`. For direct RPCs, send `PaginationRequest.token` from the previous `PaginationResponse.next_token`.
* **Timeouts:** Use `timeout` in Python, an `AbortSignal` or `defaultTimeoutMs` in TypeScript, and `context.Context` deadlines in Go.
* **Errors:** Catch typed `SDKError` subclasses for high-level workflows. Direct calls use the language's Connect error type. Replace checks for 0.x types such as `APIStatusError`, `APIConnectionError`, and `gitpod.Error`.
* **Retries:** Add retries at your application boundary only for operations that are safe to repeat. Do not assume the 0.x default of two retries still applies.

## Test the migrated application

Before deploying:

1. Run the language type checker, compiler, and tests.
2. Test authentication with `ONA_API_KEY`.
3. Create, use, and delete a disposable environment.
4. Test expected error branches, timeouts, and pagination.
5. Test `ONA_BASE_URL` if the organization uses a custom domain.
6. Remove 0.x-only imports, helpers, error types, and the old `GITPOD_API_KEY` setting.

Use the [Ona SDK guide](/docs/ona/integrations/sdk) for current installation and workflow examples.

## Troubleshooting

<Accordion title="An import for Gitpod, AsyncGitpod, or option no longer exists">
  The application still uses a 0.x import. Python code should import from `ona_sdk`, TypeScript should use named exports such as `createClientFromEnv`, and Go workflow code should import the `sdk` package.
</Accordion>

<Accordion title="Python code blocks the event loop after migration">
  The Python SDK version 1.x is synchronous. Run SDK calls in a worker thread with `asyncio.to_thread`, or move the SDK work to a synchronous worker process.
</Accordion>

<Accordion title="A direct API request has type errors after migration">
  Build the request with the generated protobuf type for that RPC. In TypeScript, use `create(RequestSchema, fields)`. In Python and Go, instantiate the generated request message. Check the API reference because 0.x parameter names and helper types do not carry over.
</Accordion>

<Accordion title="Requests fail after changing to ONA_API_KEY">
  Confirm that the process receives `ONA_API_KEY`, not only `GITPOD_API_KEY`. For custom domains, also confirm that `ONA_BASE_URL` uses the management-plane domain and ends in `/api`.
</Accordion>
