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

# Deploy

> Use client credentials to run the Zapier SDK on servers, CI pipelines, and cloud platforms.

**Client credentials** are how you authenticate the SDK on a server, in a CI
pipeline, or on a cloud platform, without interactive authentication.

You create them once locally, then make them available in your deployment environment (via environment variables, a secrets manager, or by passing them in directly) and the SDK picks them up automatically.

***

## What are client credentials?

A **client ID** and **client secret** pair that let a headless script, app, CI job, or agent authenticate to Zapier without opening a browser. They act on behalf of the Zapier user who created them, so treat the secret like a password.

***

## Step 1: Create your credentials

Do this before you deploy. Authenticate via the CLI with `zapier-sdk signup` or
`zapier-sdk login`; if that terminal cannot open a browser, add `--headless`.

Name them to reflect their purpose and environment. For example:

* `aws-lambda-sales-agent-prod`
* `github-actions-staging`
* `vercel-preview`

You will likely have a separate pair for each environment so you can rotate or revoke one without affecting the others.

### Via the CLI

```bash theme={null}
npx zapier-sdk create-client-credentials
```

```
✔ Enter name: zapier-sdk-staging

You are about to create a sensitive secret that will be displayed as plain text.
Once created, you cannot retrieve it again.

✔ Continue? Yes
{
  "client_id": "mR7kXpQ2nLtYvBsJ9dZeAf3cWhUo6gT8iNcEy4Hj",
  "name": "zapier-sdk-staging",
  "client_secret": "pK8mRzXvQnLtYwBsJ7dZeAfCWhUo6gT3iNcEy4HjVbFsDqMuOlGrP5xkR2aEhWcT9NvIpYmBsL8dZfQoX6jKwRnM4tPuHgE1cSyA0zWqFvDrTbnMcJhUl9sKxR7oYwCi"
}

Please treat this secret like a password and store it securely!
```

### Via the SDK

The SDK can also create credentials. This works because you've authenticated via the CLI, so the SDK can create credentials on your behalf.

```typescript theme={null}
import { createZapierSdk } from "@zapier/zapier-sdk";

const zapier = createZapierSdk(); // uses your CLI authentication

const { data } = await zapier.createClientCredentials({
  name: "zapier-sdk-staging",
});

// data.client_id: safe to store anywhere
// data.client_secret: only accessible here, copy it now
```

<Warning>
  **The `client_secret` is only returned once.** Copy it immediately into a
  password manager or secret store. If you lose it, delete the credential and
  create a new one.
</Warning>

***

## Step 2: Store them in your deployment environment

The two variables your SDK will read:

```bash theme={null}
ZAPIER_CREDENTIALS_CLIENT_ID=<your-generated-client-id>
ZAPIER_CREDENTIALS_CLIENT_SECRET=<your-generated-client-secret>
```

<Warning>
  **Never commit these to version control.** Use your platform's native secret
  store (examples below).
</Warning>

Where you add them depends on your platform. The steps below reflect each platform's guidance at the time of writing. Refer to their respective official documentation.

<AccordionGroup>
  <Accordion title="Railway">
    In your Railway project, open the **Variables** tab on your service and add both variables. For `client_secret`, click the three-dot menu next to the variable and choose **Seal** so the value is delivered to builds and deployments but never visible in the UI or returnable via the API. Variable changes show up as staged changes that you deploy to apply.

    See [Using Variables](https://docs.railway.com/variables) and [Sealed variables](https://docs.railway.com/variables#sealed-variables).
  </Accordion>

  <Accordion title="Vercel">
    In your Vercel project, go to **Settings > Environment Variables**. Add both variables and scope them to the appropriate environments (Production, Preview, Development, or any Custom environment). For `client_secret`, mark the variable as **Sensitive** so the value is non-readable from the dashboard or `vercel env ls` after creation. Changes only apply to new deployments, so redeploy after saving.

    See [Environment variables](https://vercel.com/docs/environment-variables) and [Sensitive environment variables](https://vercel.com/docs/environment-variables/sensitive-environment-variables).
  </Accordion>

  <Accordion title="GitHub Actions">
    In your repository, go to **Settings > Secrets and variables > Actions** and select the **Secrets** tab. Click **New repository secret** and add each value. For better isolation between staging and production, you can also create [environment secrets](https://docs.github.com/en/actions/how-tos/deploy/configure-and-manage-deployments/manage-environments) scoped to a deployment environment. Reference the secrets in your workflow file:

    ```yaml theme={null}
    env:
      ZAPIER_CREDENTIALS_CLIENT_ID: ${{ secrets.ZAPIER_CREDENTIALS_CLIENT_ID }}
      ZAPIER_CREDENTIALS_CLIENT_SECRET: ${{ secrets.ZAPIER_CREDENTIALS_CLIENT_SECRET }}
    ```

    See [Using secrets in GitHub Actions](https://docs.github.com/en/actions/how-tos/write-workflows/choose-what-workflows-do/use-secrets).
  </Accordion>

  <Accordion title="GitLab CI/CD">
    In your project, go to **Settings > CI/CD** and expand the **Variables** section. Add both variables. Under **Visibility**, choose **Masked** to replace the value with `[MASKED]` in job logs, or **Masked and hidden** for the strongest option, which also prevents the value from being revealed in the UI after creation. Optionally enable **Protect variable** to restrict the variables to pipelines on protected branches and tags only.

    See [CI/CD variables](https://docs.gitlab.com/ci/variables/) and [Mask a CI/CD variable](https://docs.gitlab.com/ci/variables/#mask-a-cicd-variable).
  </Accordion>

  <Accordion title="AWS (Lambda / ECS)">
    Store your credentials in **AWS Secrets Manager** or **SSM Parameter Store** (SecureString).

    For **ECS**, reference the secret ARNs in your task definition's `secrets` field. ECS injects the values as environment variables at runtime, and your code reads them via `process.env`.

    For **Lambda**, AWS recommends fetching the secret at runtime rather than storing it as a plaintext environment variable. Use the [Parameters and Secrets Lambda Extension](https://docs.aws.amazon.com/secretsmanager/latest/userguide/retrieving-secrets_lambda.html) to retrieve and cache the secret across invocations, or call the AWS SDK directly (the secrets-manager example in [Step 3](#loading-credentials-from-a-secrets-manager) shows the SDK pattern).

    See [Use Secrets Manager secrets in Lambda](https://docs.aws.amazon.com/lambda/latest/dg/with-secrets-manager.html) and [ECS task definition secrets](https://docs.aws.amazon.com/AmazonECS/latest/developerguide/specifying-sensitive-data-secrets.html).
  </Accordion>

  <Accordion title="Local development with isolated credentials">
    For local development that should not use the default CLI credential, for
    example when testing against staging credentials, create a `.env` file and
    load it with a tool like `dotenv`:

    ```bash theme={null}
    # .env - never commit this file
    ZAPIER_CREDENTIALS_CLIENT_ID=<your-generated-client-id>
    ZAPIER_CREDENTIALS_CLIENT_SECRET=<your-generated-client-secret>
    ```

    Add `.env` to your `.gitignore`.
  </Accordion>
</AccordionGroup>

***

## Step 3: Use your credentials

Once the environment variables are set, the SDK reads them automatically. **No code changes are required.**

```typescript theme={null}
import { createZapierSdk } from "@zapier/zapier-sdk";

// Automatically reads ZAPIER_CREDENTIALS_CLIENT_ID and
// ZAPIER_CREDENTIALS_CLIENT_SECRET from the environment
const zapier = createZapierSdk();

// Verify it's working
const { data: profile } = await zapier.getProfile();
console.log(profile);
```

### Loading credentials from a secrets manager

If your organization stores secrets in a vault like AWS Secrets Manager, HashiCorp Vault, or Doppler, you can fetch them at runtime and pass them in directly:

```typescript theme={null}
import {
  SecretsManagerClient,
  GetSecretValueCommand,
} from "@aws-sdk/client-secrets-manager";
import { createZapierSdk } from "@zapier/zapier-sdk";

const secrets = new SecretsManagerClient({ region: "us-east-1" });

const { SecretString } = await secrets.send(
  new GetSecretValueCommand({ SecretId: "zapier/staging" })
);

const { clientId, clientSecret } = JSON.parse(SecretString);

const zapier = createZapierSdk({
  credentials: { clientId, clientSecret },
});
```

### Using the CLI in a deployed environment

The CLI also reads environment variables automatically:

```bash theme={null}
# Works once env vars are set, no re-authentication needed
npx zapier-sdk list-apps
npx zapier-sdk run-action slack write channel_message ...
```

Or pass credentials explicitly as flags, useful in scripts where you want to be explicit about which credential pair is used:

```bash theme={null}
npx zapier-sdk list-apps \
  --credentials-client-id "$ZAPIER_CREDENTIALS_CLIENT_ID" \
  --credentials-client-secret "$ZAPIER_CREDENTIALS_CLIENT_SECRET"
```

***

## Security best practices

* Keep one credential pair per environment. Separate production, staging, and CI so you can rotate or revoke one without affecting the others.
* Never commit credentials to version control, even in private repositories.
* Use your platform's native secret store (Railway Variables, Vercel Environment Variables, GitHub Secrets, GitLab CI Variables, AWS Secrets Manager) rather than plain text config files.
* If you think a secret has been exposed, delete it immediately to prevent unauthorized access to your Zapier account.

***

## View your existing credentials

```typescript theme={null}
// SDK
const { data: credentials } = await zapier.listClientCredentials();
credentials.forEach((c) => console.log(c.client_id, c.name));
```

```bash theme={null}
# CLI
npx zapier-sdk list-client-credentials
```

`client_secret` is never returned in list responses. It is only shown at creation time.

***

## Rotate a credential

Rotate when a secret may have been exposed, or as part of routine key hygiene.

1. [Create a new credential](#step-1-create-your-credentials) with a name that makes the environment clear.
2. Update your deployment environment with the new credentials. Replace the values in your environment variables, secrets manager, or wherever you're providing them.
3. Redeploy and verify the SDK is working with the new credentials.
4. [Delete the old credential](#delete-a-credential) once the new one is confirmed working.
5. Remove any references to the old client ID from your secret store.

***

## Delete a credential

Delete a credential when you no longer need it, or if you think one may have been compromised.

<Warning>
  Once deleted, any code or pipeline using that `client_id` will stop
  authenticating immediately.
</Warning>

```typescript theme={null}
// SDK
await zapier.deleteClientCredentials({
  clientId: "<your-client-id>",
});
```

```bash theme={null}
# CLI
npx zapier-sdk delete-client-credentials <your-client-id>
```

After deleting, remove or update the environment variables in your deployment so the old `client_id` is not left behind.

***

## Troubleshooting

<AccordionGroup>
  <Accordion title="The SDK still asks me to log in">
    Make sure your credentials are available to the process where your code runs. If you're using environment variables, check that both are set:

    * `ZAPIER_CREDENTIALS_CLIENT_ID`
    * `ZAPIER_CREDENTIALS_CLIENT_SECRET`

    If you're passing them in explicitly via `createZapierSdk({ credentials: { clientId, clientSecret } })`, confirm the values are being fetched correctly before the SDK is initialized.

    On most platforms, environment variables only apply after a redeploy. If you recently added them, trigger a fresh deployment and try again.
  </Accordion>

  <Accordion title="I'm getting 401 or authentication errors">
    The credential may have been deleted. Run `npx zapier-sdk list-client-credentials` locally (or the SDK equivalent) to confirm the client ID still exists. If it's gone, [create a new one](#step-1-create-your-credentials) and update your environment.
  </Accordion>

  <Accordion title="I lost my client secret">
    The secret is only shown once at creation time. Delete the credential and [create a new one](#step-1-create-your-credentials), then update your deployment environment with the new values.
  </Accordion>

  <Accordion title="I accidentally committed a secret">
    Delete the credential immediately. Any code using that client ID stops authenticating right away. Create a replacement, update your environment, then remove the secret from your repository history using `git filter-repo` or your platform's secret scanning remediation tools.
  </Accordion>

  <Accordion title="How do I check which credentials are active in my account?">
    Run `npx zapier-sdk list-client-credentials` locally or call `zapier.listClientCredentials()` in the SDK. This returns all credentials with their client IDs and names, which is useful for confirming which ones exist and spotting any that should be deleted.
  </Accordion>
</AccordionGroup>

***

## Next steps

* [API Reference](/sdk/reference): full SDK method documentation
* [CLI Reference](/sdk/cli-reference): all CLI commands including `create-client-credentials`
* [Quickstart](/sdk/quickstart): getting started from scratch
