Skip to main content

Performance and Best Practices

Quick Reference

WhatPerformance optimization
WhyBuild reliable, high-throughput integrations with proper retry and idempotency
DifficultyIntermediate
PrerequisitesAuthentication → Create charge

Reliable integrations depend on idempotent requests, smart retries, and cached authentication. This guide covers every technique you need for production-grade throughput.

Rate limits

TierLimitScope
Standard100 requests / minutePer API key
Burst20 requests / secondPer API key
CustomNegotiatedEnterprise accounts
Rate limit backoff

If you receive 429 Too Many Requests, back off and retry. Never retry in a tight loop — this extends the rate-limit window and can trigger a temporary block.

Timeouts

Set client-side timeouts per operation to avoid hanging connections:

OperationRecommended timeoutNotes
Auth token10 sToken endpoint is lightweight
Create charge60 sIncludes acquirer round-trip and 3DS
3DS authentication30 sWaiting for issuer challenge
Zero auth15 sPre-authorization only
GET / list endpoints10 sRead operations

Retry strategy

Exponential backoff

import time, requests

def charge_with_retry(payload, token, max_retries=4):
for attempt in range(max_retries):
resp = requests.post("https://core-manager.a55.tech/api/v1/bank/charge/",
headers={"Authorization": f"Bearer {token}"}, json=payload, timeout=60)
if resp.status_code < 500:
return resp
time.sleep(min(2 ** attempt, 30))
return resp

Idempotency keys

Prevent duplicate charges by sending an Idempotency-Key header:

curl -X POST https://core-manager.a55.tech/api/v1/bank/charge/ \
-H "Authorization: Bearer $TOKEN" \
-H "Idempotency-Key: order_12345_attempt_1" \
-H "Content-Type: application/json" \
-d '{"amount":15000,"currency":"BRL","card_token":"tok_a55_7f3c2d1e"}'
ScenarioBehavior
Same key + same bodyReturns the original response (no new charge)
Same key + different bodyReturns 409 Conflict
No keyCreates a new charge every time
Idempotency key format

Use a deterministic format for idempotency keys: {order_id}_{attempt} or a UUID v4. Keys expire after 24 hours.

Authentication performance

Cache your access token and refresh it only when it expires:

import time, requests

class TokenCache:
def __init__(self, client_id, client_secret):
self._id, self._secret = client_id, client_secret
self._token, self._expires = None, 0

def get_token(self):
if time.time() < self._expires - 60:
return self._token
resp = requests.post("https://core-manager.a55.tech/api/v1/o/token/",
data={"grant_type": "client_credentials",
"client_id": self._id, "client_secret": self._secret}).json()
self._token = resp["access_token"]
self._expires = time.time() + resp["expires_in"]
return self._token

Optimization stack

LayerTechniqueImpact
AuthenticationToken caching with TTL bufferEliminates redundant auth calls
CredentialsStore tokens, not raw PANsFaster charges, no sensitive data on your servers
DevicePersistent device fingerprintBetter fraud scoring, fewer declines
ReliabilityIdempotency keys + exponential backoffZero duplicate charges
EfficiencyConnection pooling and keep-aliveLower latency per request
Never log secrets

Never log full card numbers, CVVs, or access tokens. Use masked PANs (**** 1111) and token references in your application logs.

Everything on this page — caching, retries, idempotency — makes your integration reliable. But the single biggest lever for approval rates is Visa Data Only: sharing enriched transaction data with issuers through 3DS rails without any challenge.

Square's pilot showed up to +646 basis points improvement. Combined with the performance techniques above, Data Only gives you both reliability and revenue.

Learn how to activate Data Only →