# Retries

API requests don't always succeed on the first attempt.

A provider might be temporarily unavailable, your network connection could timeout, or the service may return a temporary rate limit response.

These failures are often short-lived and succeed if attempted again a few moments later.

Swytchcode automatically retries these transient failures - so your applications remain reliable without requiring custom retry logic for every provider.

---

## Why Retries Matter

Imagine an AI agent creating a GitHub issue.

```text
Create Issue
      │
      ▼
GitHub API
      │
      ▼
503 Service Unavailable
```

Without retries, the request immediately fails.

With Swytchcode, the runtime detects that the error is temporary, waits briefly, and retries automatically.

```text
Attempt 1
      │
      ▼
503 Service Unavailable
      │
      ▼
Retry
      │
      ▼
Attempt 2
      │
      ▼
200 OK
```

Your application receives the successful response without writing any retry logic.

---

## How Retries Work

Every execution follows the same retry lifecycle.

```text
Execute Tool
      │
      ▼
Send Request
      │
      ▼
Receive Response
      │
      ▼
Is the error retryable?
      │
 ┌────┴────┐
 │         │
No        Yes
 │         │
 ▼         ▼
Return   Wait
Error      │
           ▼
   Retry Request
           │
           ▼
Retry Budget Remaining?
           │
     ┌─────┴─────┐
     │           │
    Yes         No
     │           │
     ▼           ▼
Retry Again   Return Error
```

The runtime continues retrying until the request succeeds or the configured retry limit is reached.

---

## Configuring Retries

Retry behavior is configured per integration in `manifest.json`.

```json
{
  "execution_policy": {
    "max_retries": 5,
    "base_delay_ms": 500,
    "max_delay_ms": 30000,
    "http_timeout_ms": 30000,
    "connect_timeout_ms": 5000,
    "total_timeout_ms": 90000,
    "retry_on": [429, 503, 504],
    "non_retryable": [400, 401, 403, 404, 422],
    "on_401": "refresh_and_retry"
  }
}
```

Every field is optional.

If a value is not specified, Swytchcode automatically uses the default execution policy.

---

## Default Retry Policy

| Field | Default |
|--------|---------|
| `max_retries` | `3` |
| `base_delay_ms` | `500 ms` |
| `max_delay_ms` | `30000 ms` |
| `http_timeout_ms` | `30000 ms` |
| `connect_timeout_ms` | `5000 ms` |
| `total_timeout_ms` | `90000 ms` |
| `retry_on` | `[429, 503, 504]` |
| `non_retryable` | `[400, 401, 403, 404, 422]` |
| `on_401` | `"fail"` |

---

## Retryable Failures

By default, Swytchcode retries failures that are likely to succeed on another attempt.

#### HTTP Status Codes

| Status Code | Meaning |
|-------------|---------|
| `429` | Too Many Requests |
| `503` | Service Unavailable |
| `504` | Gateway Timeout |

#### Network Errors

The runtime also retries temporary network failures such as:

- Connection timeouts
- Connection resets
- Temporary network interruptions
- DNS resolution failures

These failures are usually caused by infrastructure issues rather than invalid requests.

---

## Non-Retryable Failures

Some failures should never be retried because the request itself is invalid.

| Status Code | Meaning |
|-------------|---------|
| `400` | Bad Request |
| `401` | Unauthorized |
| `403` | Forbidden |
| `404` | Not Found |
| `422` | Validation Failed |

Retrying these requests would only repeat the same failure, so Swytchcode immediately returns the error to your application.

---

## Exponential Backoff

Retries are not performed immediately.

Instead, Swytchcode waits progressively longer between each attempt.

```text
Attempt 1

↓

Wait 500 ms

↓

Attempt 2

↓

Wait 1 second

↓

Attempt 3

↓

Wait 2 seconds

↓

Success
```

This exponential backoff helps prevent overwhelming providers during temporary outages.

If the provider returns a `Retry-After` header, Swytchcode respects that value instead of calculating its own delay.

---

## Retry Budget

Retries are intentionally limited.

Each integration has a configurable retry budget.

```text
Attempt 1

↓

Retry 1

↓

Retry 2

↓

Retry 3

↓

Return Error
```

Once the retry budget is exhausted, the runtime returns the final error instead of retrying indefinitely, and `swy exec` exits with code `1`.

---

## Inspecting Retries

Every attempt - including retried ones - is logged as a separate outbound network call. If you need to confirm retries actually happened (and how long each attempt took), check the local audit log rather than guessing from the final response:

```bash
swy audit network            # recent outbound calls: host, method, status, duration
swy audit network -n 20      # last 20 calls
swy audit network --info <id>  # full detail for one call (id looks like nw_...)
```

This is often the fastest way to tell "the provider was slow and we retried three times" apart from "the provider failed once and we gave up," especially when debugging a workflow that ran inside an AI agent rather than a terminal you were watching. See the [Command Reference](/reference/commands/#system) for the full `swy audit` surface.

---

## Timeout Management

Retries are governed by multiple timeout settings to prevent requests from hanging forever.

| Timeout | Purpose |
|----------|---------|
| Connect Timeout | Maximum time allowed to establish a network connection. |
| HTTP Timeout | Maximum duration for a single request. |
| Total Timeout | Maximum duration across the entire retry chain. |

This ensures requests either complete successfully or fail within a predictable amount of time.

---

## OAuth Token Refresh

For OAuth-based providers, Swytchcode can automatically recover from expired access tokens.

When enabled, the runtime performs the following steps:

```text
Execute Request
      │
      ▼
401 Unauthorized
      │
      ▼
Refresh OAuth Token
      │
      ▼
Retry Request
```

This allows requests to continue without requiring the user to manually reconnect their account.

The behavior is controlled by the `on_401` option in the integration's execution policy.

---

## Best Practices

- Retry only transient failures.
- Do not retry validation or authorization errors.
- Respect provider rate limits and `Retry-After` headers.
- Configure retry policies for each integration independently.
- Keep retry budgets reasonable to avoid long-running requests.
- Combine retries with idempotency for safe execution of mutating APIs.
- Test retry behavior in sandbox environments before deploying to production.

## Related guides

- [Execution Pipeline](https://docs.swytchcode.com/guides/execution-pipeline/) - Understand how retries fit into the runtime pipeline.
- [Idempotency](https://docs.swytchcode.com/guides/idempotency/) - Learn how duplicate operations are prevented when retries happen.
- [Production Guardrails](https://docs.swytchcode.com/policies/production-guardrails/) - Guidance on retry and idempotency policy configuration.
