"Rate limiting" on the Acumatica REST API doesn't work the way it does on most SaaS APIs. There's no documented token-bucket or requests-per-minute quota returning a clean 429 Too Many Requests with a Retry-After header. What you actually run into is a concurrency limit tied to your license.
It's a concurrency limit, not a quota
Acumatica licenses define a number of concurrent API "cores" — the number of requests the instance will process for integration users at the same time. When every core is busy, the next request doesn't get rejected outright; it queues and waits for a core to free up. That's a meaningfully different failure mode than a typical rate limit: instead of a fast, explicit rejection you can detect and back off from, you get a slow request that looks identical to any other slow request until it eventually times out on your side.
Acumatica's public documentation doesn't describe a 429-based throttling contract the way Shopify or Stripe do. Treat any specific numeric limit you're quoted (requests per minute, concurrent cores) as license- and deployment-dependent, and verify it against the actual License Monitoring Console on the instance you're integrating with rather than a number from an old forum post.
What actually throttles you in practice
In practice, the limiting factor is almost always one of: the number of concurrent API-user sessions your license allows, the number of application pool worker processes IIS has available, or plain database contention from a long-running screen-equivalent operation (a Sales Order save with heavy business logic is not cheap, REST or not). A burst of parallel requests from an integration is far more likely to produce timeouts and queuing than an explicit rejection.
Reading the signals: timeouts vs. explicit errors
Because there's no clean throttle signal, your retry logic needs to treat HTTP timeouts and 5xx responses as "maybe transient, maybe not" rather than assuming every failure is a bug in your payload. A 400 with a validation message from PXException is not retryable — retrying it will fail identically every time. A timeout, a 502/503 from IIS, or a connection reset is a reasonable candidate for retry with backoff.
A retry strategy that respects queuing, not just backoff
Exponential backoff with jitter is still the right shape, but size it around the fact that you're waiting for a core to free up, not for a token bucket to refill — a few seconds of backoff is often too short if the instance is genuinely saturated. Cap retries (three to five attempts is typical) and make sure retried writes are idempotent — which, thanks to PUT-based upserts, they usually are as long as you include the record's key fields.
var retryPolicy = Policy
.Handle<TaskCanceledException>() // timeout
.OrResult<HttpResponseMessage>(r =>
(int)r.StatusCode >= 500 || r.StatusCode == HttpStatusCode.RequestTimeout)
.WaitAndRetryAsync(
retryCount: 4,
sleepDurationProvider: attempt =>
TimeSpan.FromSeconds(Math.Pow(2, attempt)) +
TimeSpan.FromMilliseconds(new Random().Next(0, 500)));
var response = await retryPolicy.ExecuteAsync(() => httpClient.PutAsync(url, content));
Where the real bottleneck usually is
Before tuning retry policy, check whether the integration is even using its concurrency budget well. A common mistake is firing dozens of parallel PUTs at a single endpoint from a batch job — that's the fastest way to exhaust the API core limit and start seeing queuing that looks like a rate limit but is really self-inflicted contention. Throttling your own concurrency client-side (a semaphore capping simultaneous in-flight requests) is usually more effective than any amount of retry tuning.
Wrapping up
There's no documented rate-limit contract to code against — there's a concurrency ceiling tied to your license and infrastructure. Retry on timeouts and 5xx, never on validation errors, back off with real headroom, and throttle your own client concurrency before you assume the API is the bottleneck.
Independent software engineer in Nairobi specialising in Acumatica customisations, Laravel backends, and tax fiscalisation integrations across East and Southern Africa.