Rate Limits
Understand API rate limiting and how to handle rate limit errors
If you have questions or issues related to an API service in the Pilot or Live environments, please contact the Swift Customer Support Center.
Rate limiting controls the number of requests a client can make to an API within a given time period. It protects the API from being overwhelmed, prevents abuse, and ensures fair usage among all clients.
Rate limits are enforced at the institution level (BIC4).
How to interpret the setting value
For example, when you see a value of 50 ps in the setting column, then it means a minimum of 1000/50 = 20 milliseconds between 2 consecutive API calls.
| API | Pilot | Live |
|---|---|---|
| Payment Pre-validation API | 100 ps | 100 ps |
| Tracker Frontend API | 100 ps | 100 ps |
| Network Interoperability | 100 ps | 100 ps |
Handling rate limit errors
When you exceed the rate limit, the API returns HTTP status code 429 - Too Many Requests. This is a transient error, meaning your application should retry the request after a short delay.
{
"severity": "Transient",
"code": "SwAP507",
"text": "Request cannot be processed at this time. Please try again."
}Best practices
- Implement throttling: Limit the rate of outgoing API calls from your application to stay within the allowed limits.
- Use exponential backoff: When retrying after a
429error, wait progressively longer between each retry attempt. - Monitor usage: Track your API call volume to identify patterns and optimise request frequency.
Example retry logic
async function callApiWithRetry(requestFn, maxRetries = 3) {
for (let attempt = 0; attempt < maxRetries; attempt++) {
const response = await requestFn();
if (response.status === 429) {
const delay = Math.pow(2, attempt) * 1000; // 1s, 2s, 4s
await new Promise(resolve => setTimeout(resolve, delay));
continue;
}
return response;
}
throw new Error('Rate limit exceeded after maximum retries');
}import time
import requests
def call_api_with_retry(request_fn, max_retries=3):
for attempt in range(max_retries):
response = request_fn()
if response.status_code == 429:
delay = (2 ** attempt) # 1s, 2s, 4s
time.sleep(delay)
continue
return response
raise Exception('Rate limit exceeded after maximum retries')public Response callApiWithRetry(Supplier<Response> requestFn, int maxRetries)
throws Exception {
for (int attempt = 0; attempt < maxRetries; attempt++) {
Response response = requestFn.get();
if (response.getStatusCode() == 429) {
long delay = (long) Math.pow(2, attempt) * 1000; // 1s, 2s, 4s
Thread.sleep(delay);
continue;
}
return response;
}
throw new Exception("Rate limit exceeded after maximum retries");
}import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.retry.annotation.Backoff;
import org.springframework.retry.annotation.Retryable;
import org.springframework.stereotype.Service;
import org.springframework.web.client.HttpClientErrorException;
import org.springframework.web.client.RestTemplate;
@Service
public class ApiService {
private final RestTemplate restTemplate;
public ApiService(RestTemplate restTemplate) {
this.restTemplate = restTemplate;
}
@Retryable(
retryFor = HttpClientErrorException.TooManyRequests.class,
maxAttempts = 3,
backoff = @Backoff(delay = 1000, multiplier = 2)
)
public ResponseEntity<String> callApiWithRetry(String url) {
return restTemplate.getForEntity(url, String.class);
}
}public async Task<HttpResponseMessage> CallApiWithRetryAsync(
Func<Task<HttpResponseMessage>> requestFn,
int maxRetries = 3)
{
for (int attempt = 0; attempt < maxRetries; attempt++)
{
var response = await requestFn();
if (response.StatusCode == HttpStatusCode.TooManyRequests)
{
var delay = (int)Math.Pow(2, attempt) * 1000; // 1s, 2s, 4s
await Task.Delay(delay);
continue;
}
return response;
}
throw new Exception("Rate limit exceeded after maximum retries");
}package main
import (
"errors"
"math"
"net/http"
"time"
)
func callAPIWithRetry(requestFn func() (*http.Response, error), maxRetries int) (*http.Response, error) {
for attempt := 0; attempt < maxRetries; attempt++ {
response, err := requestFn()
if err != nil {
return nil, err
}
if response.StatusCode == http.StatusTooManyRequests {
delay := time.Duration(math.Pow(2, float64(attempt))) * time.Second // 1s, 2s, 4s
time.Sleep(delay)
continue
}
return response, nil
}
return nil, errors.New("rate limit exceeded after maximum retries")
}