Skip to content

manifest.json is the integration registry for your Swytchcode project.

It stores metadata about every installed integration, including its version, API endpoints, authentication configuration, and execution behavior.

Unlike tooling.json, which defines what can execute, manifest.json defines how an integration executes.

The file is located at:

.swytchcode/integrations/manifest.json

Every integration installed using swy get or swy add automatically updates this file.

Both the CLI and the MCP server share this file during execution. Updates are serialized to prevent corruption when multiple tools modify it simultaneously.


What does manifest.json do?

For every installed integration, Swytchcode stores:

  • Integration version
  • Sandbox endpoint
  • Production endpoint
  • Authentication metadata
  • Method count
  • Workflow count
  • Execution policy

During execution, the kernel reads this file to determine:

  1. Which endpoint should receive the request
  2. How authentication should work
  3. Whether retries are allowed
  4. Timeout behavior
  5. Idempotency settings
  6. Concurrency limits

File Structure

A simplified example looks like this:

{
"stripe.stripe": {
"version": "v2",
"sandbox_endpoint": "https://api.stripe.com",
"production_endpoint": "https://api.stripe.com",
"methods": 42,
"workflows": 3,
"auth": {
"type": "api_key",
"header": "Authorization"
}
}
}

Each top-level key represents a single integration.


Entry Fields

Each integration contains the following fields.

version

Defines the pinned version of the integration, e.g. "v2". This is the same version string that appears next to the integration in tooling.json.integrations (for example "stripe.stripe": { "version": "v2" }) - the two files must agree, since swy bootstrap and swy sync compare them to decide what to fetch.

{
"version": "v2"
}

Swytchcode always executes using the pinned version stored in the manifest, never “whatever is newest.” If you want a newer integration version, run swy get <project> again to fetch the new bundle and update this file - editing the field by hand won’t fetch anything.


sandbox_endpoint

Defines the base URL used when the project is running in sandbox mode (tooling.json.mode: "sandbox").

{
"sandbox_endpoint": "https://sandbox.example.com"
}

Many providers (Stripe is a common example) use the same host for sandbox and production and distinguish environments by which API key you authenticate with instead of by URL - in that case sandbox_endpoint and production_endpoint are identical, as shown in the Complete Example below.


production_endpoint

Defines the base URL used for production execution (tooling.json.mode: "production").

{
"production_endpoint": "https://api.example.com"
}

Because the environment is resolved from tooling.json.mode rather than from a flag on exec, switching a project from sandbox to production means changing mode in tooling.json (or re-running swy init --mode=production) once, rather than remembering to pass an environment flag on every call.


methods

Number of executable methods included in the integration bundle, e.g. 42.

{
"methods": 42
}

This value is informational - it reflects what’s available in the fetched bundle under .swytchcode/integrations/, not what’s enabled in your project. Use swy list tooling to see what’s actually been added via swy add, and swy info <canonical_id> to inspect one method in detail. It’s maintained automatically by swy get, swy bootstrap, and swy sync; don’t hand-edit it.


workflows

Number of workflows provided by the integration, e.g. 5.

{
"workflows": 5
}

Same caveat as methods: this counts what’s in the bundle, not what’s registered in tooling.json.tools. Run swy add workflow <canonical_id> to actually enable one.


auth

Authentication metadata used by Swytchcode to know how to authenticate against this provider - it’s the schema, not the secret. The actual key or token is never stored here; it’s resolved separately at execution time (see Managed Authentication).

Example:

{
"auth": {
"type": "api_key",
"header": "Authorization"
}
}

Depending on the integration, authentication metadata may include:

  • Authentication type (api_key or oauth)
  • OAuth scopes
  • Authorization header name
  • Token format

swy auth connect [provider] reads this block to decide whether to prompt for an API key or start an OAuth flow, and swy auth connect with no argument reads it across every installed integration to list which providers still need credentials. swy doctor also checks this block as part of validating that installed integrations are fully configured.


execution_policy

Defines how HTTP requests to this integration behave: retries, timeouts, concurrency, response-size limits, and idempotency. Every field is optional and unset fields fall back to the built-in defaults - see the full Execution Policy breakdown below for every field, its default, and when to change it.


Environment Selection

Swytchcode automatically chooses the correct endpoint using the project mode defined in tooling.json.

tooling.json
mode = sandbox
sandbox_endpoint
tooling.json
mode = production
production_endpoint

The final request URL is built as:

Base URL
+
Method Endpoint
=
Final Request URL

For example:

https://api.stripe.com
+
/v1/customers
=
https://api.stripe.com/v1/customers

Whenever a request executes, Swytchcode prints the active environment.

Example:

Running live - stripe (production)

This prevents accidental production requests.

If you’re not sure an endpoint is reachable before you run a real workflow against it, swy doctor --network checks every configured endpoint (sandbox and production, across all installed integrations) and reports its current status.


URL Security Rules

Swytchcode enforces URL safety automatically.

HTTPS

HTTPS is supported for every host.

https://api.stripe.com

HTTP

HTTP is only allowed for local development.

Supported hosts:

  • localhost
  • 127.0.0.1
  • ::1

Requests to external HTTP endpoints are rejected.


Self-signed certificates

For local development, TLS verification can be disabled.

Terminal window
SWYTCHCODE_INSECURE=1

This is only allowed outside CI environments.

When running in GitHub Actions, GitLab CI, or other supported CI environments, insecure TLS is always rejected.


Execution Policy

The execution_policy object controls how HTTP requests are executed for a single integration: retry attempts, retry delays, timeouts, concurrency, response-size limits, and idempotency. It lives inside that integration’s entry in manifest.json, so different integrations can have different policies - a flaky third-party API might get a higher max_retries while an internal service you fully trust gets none.

Every field is optional. You only need to set the fields you want to override; Swytchcode merges the rest with its built-in defaults (documented field-by-field below).

Example - retry more aggressively and allow more time per request for a slow provider:

{
"execution_policy": {
"max_retries": 5,
"http_timeout_ms": 60000
}
}

Retry Configuration

max_retries

Maximum retry attempts after the first request.

Default:

3

Negative values are treated as 0.


retry_on

HTTP status codes that trigger retries.

Default:

[
429,
503,
504
]

non_retryable

Status codes that are never retried.

Default:

[
400,
401,
403,
404,
422
]

on_401

Determines what happens when authentication fails.

Supported values:

ValueDescription
failImmediately fail the request.
refresh_and_retryRefresh OAuth credentials once and retry.

Default:

{
"on_401": "fail"
}

Retry Delays

base_delay_ms

Initial retry delay.

Default:

500

(milliseconds)


max_delay_ms

Maximum retry delay.

Default:

30000

(milliseconds)


Timeouts

connect_timeout_ms

Maximum DNS and TCP connection time.

Default:

5000

http_timeout_ms

Maximum duration for an individual request.

Default:

30000

total_timeout_ms

Maximum duration including all retries.

Default:

90000

Concurrency

max_concurrent

Limits parallel requests to a provider.

Default:

5

Setting the value to 0 or a negative number disables the limiter.


Response Size

max_response_bytes

Maximum response size before truncation.

Default:

102400

(bytes)

Values less than or equal to zero disable response truncation.


Idempotency

Mutating APIs sometimes receive duplicate requests due to retries or network failures.

The idempotency object prevents duplicate operations by attaching an idempotency key.

Example:

{
"idempotency": {
"mode": "dynamic",
"scope": "workflow"
}
}

mode

Determines whether idempotency is enabled.

ValueDescription
noneDisable idempotency.
dynamicAutomatically attach an idempotency key.

Default:

none

header_name

Header used for the idempotency key.

Default:

Idempotency-Key

scope

Determines how keys are generated.

ValueDescription
callNew key for every request.
workflowStable key across workflow execution.

Complete Example

{
"stripe.stripe": {
"version": "v2",
"sandbox_endpoint": "https://api.stripe.com",
"production_endpoint": "https://api.stripe.com",
"methods": 42,
"workflows": 3,
"auth": {
"type": "api_key",
"header": "Authorization"
},
"execution_policy": {
"max_retries": 5,
"on_401": "refresh_and_retry",
"max_concurrent": 3,
"idempotency": {
"mode": "dynamic",
"scope": "workflow"
}
}
}
}

How manifest.json Fits into Execution

Every API execution follows the same flow.

tooling.json
│ Is this tool trusted?
policies.json
│ Is this request allowed?
manifest.json
│ Which endpoint?
│ Which auth?
│ Retry policy?
│ Timeout?
│ Idempotency?
Execute API Request

tooling.json defines what can execute.

policies.json defines whether it should execute.

manifest.json defines how it executes.

Together, these three files form the core execution model of Swytchcode.


Best Practices

  • Do not edit generated values unless necessary.
  • Commit manifest.json to version control.
  • Keep integration versions pinned.
  • Prefer sandbox mode during development.
  • Configure retries based on the API provider.
  • Enable idempotency for mutating operations.
  • Review timeout settings for long-running APIs.

Continue learning about the execution pipeline: