Wide enterprise API operations scene showing an Acumatica REST request entering an asynchronous processing loop with 202, Location polling, 204, and 409 status markers.

Acumatica REST long-running operations require a two-part client workflow: start the action, then wait for the server-side work to finish before sending a dependent request in the same session. When an action returns 202 Accepted, capture its Location response header and poll that URL with GET. Continue while the status endpoint returns 202; treat 204 No Content as successful completion. Acumatica’s current REST documentation also says that, while a long-running operation is executing on a form in the current session, only the request that retrieves that operation’s status can succeed; other same-session requests can fail until completion.[1][2]

That protocol is simple on a whiteboard and easy to mishandle in production. Clients often log only the response body, discard the Location header, confuse an HTTP timeout with cancellation of the server process, or immediately send the next action through the same session. The result can be intermittent conflicts, including the familiar message that a long operation is already running for the screen. This guide turns the documented 202-to-204 flow into a resilient integration pattern with explicit session ownership, bounded polling, careful retry decisions, and verification after completion.

This reliability pattern belongs beside broader release planning. If you are preparing an environment change as well as an integration change, start with Biz-Tech’s Acumatica 2026 R2 upgrade planning guide and then validate the long-running paths described here against the exact build you intend to deploy.

Table of Contents

What Acumatica means by a long-running REST operation

An Acumatica REST action can initiate work that outlives the request that started it. Releasing a financial document, confirming a shipment, preparing an invoice, generating a report, or processing a group of records may require business logic, database work, external service calls, and transaction processing that should not keep one HTTP request open until every step finishes.

For an endpoint action, the client sends an HTTP POST to the top-level entity and action name. Acumatica documents two successful outcomes. If the action completed immediately or no long operation was created, the response can be 204 No Content. If processing is still underway, the response is 202 Accepted, and the Location header identifies the operation-status resource.[1]

The important distinction is acceptance versus completion. The HTTP specification defines 202 Accepted as a request accepted for processing whose processing is not yet complete. The response is deliberately noncommittal: the work might later succeed or fail. By contrast, 204 No Content means the server successfully fulfilled the request and has no response content to send.[5] In Acumatica’s action protocol, 204 from the status URL is the signal that the long-running operation finished.

This means a 202 response is not a green light for the next dependent business request. It is a transition into a monitoring phase. The integration owns that monitoring phase until completion, timeout, cancellation, or a terminal error is recorded.

The response contract 202 Location 204 and 409

The safest implementation treats each response as a distinct control signal.

202 Accepted. The requested action is still in progress. Read the Location response header, resolve it against the request URI if it is relative, and begin polling that status URL. Do not infer the URL from the action name or construct it manually when the server has supplied it. Acumatica’s current example shows a status path that includes the endpoint, entity, action, status segment, and an operation identifier.[2]

204 No Content from the original action. The operation completed synchronously or no long-running operation was created. There is no body to parse. Continue to the business-level verification step rather than starting a polling loop.[1]

204 No Content from the status URL. The asynchronous work has finished. Stop polling. Then retrieve the affected document or other business object and verify the expected state, because transport completion does not by itself prove that every downstream business expectation was met.

409 Conflict. RFC 9110 defines 409 as a conflict between the request and the current state of the target resource.[5] Acumatica’s action documentation does not list 409 as a universal response for every action, but recent community cases show it accompanying a message such as “A long operation is running for this screen in the current session.”[7] Treat that combination as evidence of session or form contention, not as a generic invitation to retry every request immediately.

Other terminal errors. Acumatica documents 400, 401, 403, 404, 422, 429, and 500 for action calls.[1] Each needs its own policy. Authentication failures should stop and refresh or reauthenticate according to the configured flow. Validation errors should be surfaced with field details. Rate limits need backoff and capacity planning. Server errors need bounded retries only when the operation’s state is known well enough to avoid duplication.

Model the workflow as a state machine

Production code is easier to reason about when the operation is represented explicitly instead of being buried inside one HTTP helper. A useful state machine has six states.

  1. Ready. The integration has a valid authenticated session and no outstanding operation assigned to that session-and-form lane.
  2. Starting. The client sends the action request once and records the request fingerprint, document keys, endpoint, action, session identifier, and start time.
  3. Polling. The start response was 202; the client stored the Location URL and is allowed to send only status requests through that lane.
  4. Completed. The start response or the status request returned 204. Polling stops, but business verification has not yet occurred.
  5. Verified. A follow-up read confirms the expected document or process state.
  6. Indeterminate or failed. The client lost the response, reached its deadline, received an unexpected status, lost the session, or found a business result that does not match the requested action.

The difference between Completed and Verified matters. Suppose ReleaseSalesInvoice reaches 204, but a follow-up read shows the invoice still on hold or in an unexpected status. The HTTP monitoring protocol is complete, yet the integration outcome is not acceptable. That condition deserves a business error, not a successful job record.

An indeterminate state is equally important. If the TCP connection drops after Acumatica accepted the action but before the client receives 202, the client cannot safely assume that nothing happened. Blindly repeating the action might duplicate an external side effect or hit a form that is already busy. The recovery path should query the relevant business record, consult stored operation data if available, and escalate when the action cannot be proven safe to repeat.

Recognize which requests can become asynchronous

Acumatica’s documented flow applies to actions performed through the contract-based REST API. The request URL includes the base endpoint, top-level entity, and action name, and the request body identifies the record and any action parameters.[1] Examples include release, confirm, prepare, process, and report-generation operations, but the exact behavior depends on the endpoint, action, version, configuration, and customizations.

Do not build a global rule that every POST is asynchronous or every PUT is synchronous. Instead, define an operation profile for each integration step:

  • HTTP method and endpoint path;
  • expected synchronous success statuses;
  • whether 202 is documented or observed;
  • whether Location is required when 202 occurs;
  • the business record used for post-completion verification;
  • retry safety and possible external side effects;
  • session and form concurrency constraints;
  • expected duration under representative load.

Acumatica’s official C# client reinforces this action-specific design. Its InvokeActionAsync method sends the action, verifies the response, and returns the Location header. Its WaitActionCompletionAsync method repeatedly retrieves process status, returns on 204, continues on 202, and treats other results as exceptional.[3] The official console example wraps shipment confirmation, invoice preparation, and invoice release calls with WaitActionCompletion before moving to the next dependent step.[4]

That pattern is more reliable than trying to infer long-running behavior from elapsed time. A request that returns quickly may have only queued the real work. A request that takes several seconds might still complete synchronously. Status and headers are the protocol; duration is only telemetry. Biz-Tech’s practical Acumatica integration lessons provide more context for treating API behavior, process ownership, and recovery as one system.

Capture the Location header correctly

The Location value is a response header, not a JSON field. Logging only the response body will miss it. That omission is one reason integrations appear to receive an “empty successful response” and then unexpectedly collide with a still-running operation.[7]

Capture at least these values for every action response:

  • HTTP method and sanitized request URI;
  • status code;
  • Location header, if present;
  • correlation or trace identifiers exposed by the application, proxy, or client;
  • elapsed request time;
  • session lane identifier, never raw credentials or sensitive cookies;
  • entity keys and action name;
  • a redacted response body for errors.

When the status is 202, validate that Location exists and contains a usable URI reference. RFC 9110 allows Location to be relative; resolve it against the effective request URI.[5] Restrict the resolved URL to the expected Acumatica origin unless your architecture intentionally supports a trusted alternate host. This prevents a malformed or compromised response from turning the polling client into an arbitrary URL fetcher.

Do not synthesize the status URL from a copied example. Endpoint names, versions, entities, action names, locale segments, and operation identifiers vary. Use the value returned by the target instance. Store it as operation data, protect it as potentially sensitive telemetry, and retain it long enough to diagnose a failed run.

A 202 without a usable Location is a protocol error. Do not send the next dependent request and do not pretend that sleeping for a fixed interval is equivalent to monitoring. Record the response headers, endpoint version, build, and action, then stop or enter a controlled recovery path.

Poll in the same authenticated session

The status request must preserve the authentication and session context associated with the action. With cookie-based login, that means reusing the same cookie container or HTTP client. With OAuth 2.0 or OpenID Connect, it means preserving the applicable authorization context and, when concurrent access session IDs are managed through cookies, the documented Cookie header behavior.[1]

Acumatica’s official client constructs its HttpClient with a CookieContainer, retains the ASP.NET_SessionId, and uses the same client for action invocation and process-status requests.[3] That implementation detail reflects an operational rule: an operation started in one session might not be visible from another. The official client even maps a 404 during status retrieval to a message that the process may have been started in another session.[3]

The session relationship creates two obligations.

First, do not let a generic HTTP client factory replace or clear the cookie container between the action and the poll. A new client instance with the same username is not automatically the same server session. Likewise, load-balanced environments must preserve whatever affinity and cookie behavior the deployment requires.

Second, do not use the polling session for unrelated work while the operation is active. Acumatica states that only the status request can execute successfully for a form with a long-running operation in the current session; other requests in that session fail until completion.[1] A shared session pool that ignores this rule can cause one worker to interfere with another even when the business records are unrelated.

Treat the session as leased to the operation. The lease begins when the start request is sent and ends only after terminal status, verification, and cleanup. If the session is lost, mark the operation indeterminate and use an explicit recovery policy. That lifecycle matters in real connector designs such as ShipStation-to-Acumatica data flows and DSCO-to-Acumatica data flows, where business sequencing and session ownership must agree.

Choose a safe polling interval and deadline

Polling too aggressively wastes application capacity and can worsen the load that made an operation slow. Polling too slowly increases end-to-end latency and holds a session lane longer than necessary. Acumatica’s current documentation requires a delay between status checks but does not prescribe one universal interval.[2] The official C# client defaults to a one-second interval.[3] A community answer suggests two to five seconds as a reasonable range in one scenario.[6]

Use those values as starting points, not promises. A practical policy is:

  • start at one or two seconds for interactive operations expected to finish quickly;
  • increase the delay gradually for longer operations;
  • add small random jitter so many workers do not poll in lockstep;
  • cap the interval so completion is still detected promptly;
  • honor a server-provided retry signal if the endpoint supplies one and your implementation has verified its meaning;
  • enforce an overall deadline based on the action’s normal and worst-case duration.

For example, delays could progress from 1 second to 2, 3, 5, 8, and then remain capped at 10 seconds. Jitter of plus or minus 10 to 20 percent spreads load without materially delaying completion. The exact values should come from measurements on the target build, data volume, customization set, and infrastructure.

The deadline should be longer than the HTTP request timeout for each poll. Each GET needs its own network timeout, while the whole operation needs a separate elapsed-time deadline. When the overall deadline expires, stop issuing automatic status requests, record the operation as timed out or indeterminate, and follow a recovery workflow. Do not automatically conclude that Acumatica stopped processing.

Separate client cancellation from server completion

Cancelling an HTTP request usually stops the client from waiting; it does not prove that the server-side operation was cancelled. A cancellation token, socket timeout, reverse-proxy timeout, or job-runner shutdown can all end the local wait while Acumatica continues processing.

This distinction explains a common failure sequence:

  1. The integration posts an action.
  2. The client times out or is cancelled.
  3. The worker assumes the action stopped.
  4. The worker immediately retries or sends the next request in the same session.
  5. Acumatica reports a conflict because the original operation is still running.

The correct response to cancellation depends on what the client knows. If it already received 202 and saved the Location, the operation can be resumed by a recovery worker that owns the same session context, subject to authentication and deployment constraints. If it never received the start response, the outcome is uncertain. Query the business record and any safe operation history before deciding to replay.

Design cancellation as a state transition, not an exception that erases context. Persist the action fingerprint, start time, session lane, last status, status URL, poll count, and last successful communication. A shutdown handler can then release or transfer ownership without claiming that the server task was cancelled.

If the business needs true cancellation, verify that the specific Acumatica operation exposes a supported cancellation mechanism. Do not assume that cancelling the HTTP call provides it.

Handle 409 conflicts without creating duplicates

A 409 Conflict says that the request cannot be completed in the resource’s current state.[5] In an Acumatica integration, one possible current-state conflict is a form that is already executing a long-running operation in the same session. A recent community case reported a 409 and the message “A long operation is running for this screen in the current session. Please try again later.” The discussion traced the issue to a prior action whose 202 and Location header were not being monitored.[7]

Do not reduce all 409 responses to “sleep and retry.” First classify the conflict:

  • Does the response body identify an active long operation?
  • Did a previous request in the same session return 202?
  • Is there a stored Location URL for that session lane?
  • Is the conflicting request an action, a record update, or another operation?
  • Could a retry repeat a financial, fulfillment, payment, or external-system side effect?

If an outstanding status URL exists, resume or continue polling it. When it reaches 204, verify the business result, then decide whether the rejected request is still necessary. A request rejected before it reached business processing may be safe to send once after the lane is free, but that conclusion should come from endpoint-specific tests and logs.

If there is no captured Location, inspect the immediately preceding requests, including headers and statuses. The Location belongs to the call that started the operation, not to the later request that conflicts.[7] If the initiating response was lost, move into an indeterminate recovery path rather than repeatedly hammering the endpoint.

Use bounded attempts. Repeated 409 responses after the expected operation duration can indicate a stuck session, failed cleanup, a customization, or an unexpected action path. Preserve the evidence and escalate with the instance build, endpoint version, form, request sequence, correlation IDs, and System Monitor observations.

Isolate sessions when work must run concurrently

One integration worker often handles several document pipelines at once. The tempting design is a singleton authenticated client shared by every worker. That is efficient for sockets but dangerous for session-scoped long operations. If one action leases the session and form lane, another worker can collide with it.

Use a session manager that makes concurrency explicit. Common models include:

  • one authenticated session per sequential integration worker;
  • a bounded pool of session lanes, each allowing only one outstanding long operation for an affected form;
  • separate service principals or OAuth concurrent-access sessions where licensing, security policy, and Acumatica configuration permit them;
  • a queue keyed by session and form, so dependent operations serialize while unrelated lanes can proceed.

Do not create unlimited sessions as a workaround. Acumatica documents 429 when requests exceed license restrictions, and session limits are part of capacity planning.[1] A safe pool has a configured maximum, health checks, idle expiration, and metrics for wait time and utilization.

Session isolation does not remove business-level concurrency hazards. Two sessions can still attempt incompatible changes to the same order or invoice. Use document-level coordination, optimistic concurrency where available, and post-write verification. Session lanes protect the REST conversation; they do not replace business locking or workflow rules.

Also define ownership for a status URL. Exactly one worker should poll a given operation at a time. If a worker crashes, a lease timeout can allow recovery, but the replacement must use the correct session context or deliberately enter a documented alternative recovery path.

Do not assume every PUT participates in the 202 flow

Developers often add if status == 202 logic around one action and expect it to explain every later conflict. That fails when the integration’s problematic request is a different method or when an earlier hidden action started the work.

Acumatica’s documented action execution uses POST; record creation and update commonly use PUT.[1] In the recent Sales Orders community case, the developer’s order-creation PUT returned 200 or a later 409, while the relevant 202 was associated with an action call in the sequence.[7] That observation should not be turned into a permanent rule that a PUT can never involve server-side long work. Customizations, external tax, payment processing, and version-specific behavior can complicate the lifecycle.

Instead, log the complete request sequence. For each call, record method, endpoint, status, response headers, elapsed time, and session lane. Then map the sequence around the conflict:

  1. Which call last succeeded?
  2. Did any prior response return 202?
  3. Was its Location stored and polled?
  4. Did a network timeout hide the response?
  5. Did the application reuse the session concurrently?
  6. Does the target build behave differently from the integration’s test build?

This evidence-first approach prevents a client from waiting on the wrong request or looking for a Location header on the 409 response itself. It also respects the topic brief’s key accuracy constraint: long-operation behavior must be validated for the target endpoint and build, not presented as a universal defect in a specific release.

Verify the business result after 204

204 is the end of the status-monitoring protocol, not the end of integration validation. After completion, perform a fresh GET for the affected entity and check the fields that define success.

For a released invoice, that may include the document status, hold flag, released flag, batch reference, and expected financial totals. For a confirmed shipment, it may include confirmation status, shipment number, packages, tracking data, and linked orders. For a processing action, it may include per-record results and error fields. For a report, completion may lead to a separate retrieval response containing the generated file rather than a document-state check.

Verification should be narrow and deterministic. Do not compare an entire payload when only three fields define completion. Record the expected values before starting the action, then evaluate them after 204. If the result is eventually consistent, allow a short, bounded read-after-completion retry policy that is separate from the long-operation poll.

This extra read provides three benefits. It confirms the business effect, produces evidence for support, and makes retries safer. A job that restarts after losing its local success record can check whether the document already reached the intended state before repeating the action.

When verification fails, preserve both layers of evidence: the successful operation-status trace and the unexpected business payload. That distinction helps determine whether the issue lies in the action, a customization, downstream processing, or the client’s success criteria.

Make retries safe with operation-aware idempotency

Retries are not a single feature. A network retry, a conflict retry, a status-poll retry, and a business-action replay have different risk.

Status GET retries are normally the least risky because they retrieve operation state. Retry transient connection failures with bounded backoff while the overall deadline remains open.

Start-request retries before any response are risky because the server might have accepted the first request. Before replaying, query the business record and operation evidence. If the action cannot be proven idempotent, send the case to manual review.

Retries after a documented rejection may be safer when logs prove the request never entered business processing. Even then, confirm that the endpoint and build behave as expected.

Retries after 204 should usually become verification reads, not repeated actions. Reissuing a release, payment capture, shipment confirmation, or external call after success can generate errors or duplicate effects.

Create an operation key from stable business inputs such as tenant, entity, document type, document number, action, and an integration job identifier. Store the key before starting. The record should include the action request hash, timestamps, responses, Location, final status, and verification result. On restart, the worker consults that ledger before deciding whether to start, resume, verify, or escalate.

Do not claim idempotency merely because the HTTP method is commonly described as idempotent. Business actions invoked with POST often are not. A custom endpoint might also produce external side effects that Acumatica cannot roll back. Idempotency must be established at the operation and business level.

Instrument the entire operation lifecycle

Long-running integrations are difficult to support when logs contain only “request failed.” Observability should reconstruct the timeline without exposing credentials or sensitive business data.

Record structured events for action start, start response, poll attempt, poll response, completion, verification, timeout, cancellation, conflict, retry decision, and manual escalation. Include:

  • operation key and correlation ID;
  • tenant or company identifier in an approved, non-sensitive form;
  • endpoint name and version;
  • entity, action, and sanitized document key;
  • session lane identifier;
  • HTTP status and elapsed time;
  • redacted Location fingerprint and optionally the protected full URL;
  • poll count and next delay;
  • final business verification outcome;
  • Acumatica build and customization package version when available.

Useful metrics include action acceptance rate, synchronous completion rate, long-operation duration percentiles, poll count, 409 count by action, timeouts, session-pool saturation, 429 responses, verification failures, and recovery outcomes. Alert on trends, not isolated slow calls. A rising 409 rate paired with missing Location values usually points to a client instrumentation or sequencing problem; a duration shift after an upgrade may point to data, customization, or environment changes.

Protect logs carefully. Cookies, access tokens, raw authorization headers, personally identifiable information, payment data, and complete financial documents do not belong in general application logs. Redact at the logging boundary rather than relying on operators to avoid sensitive fields.

Finally, make the trace easy to export. A support bundle containing the ordered request timeline, statuses, headers, build, endpoint version, and document keys is far more actionable than screenshots of a final error.

Production ready polling pseudocode

The following pseudocode emphasizes state ownership and decision points rather than a particular language:

function executeAction(sessionLane, actionRequest, policy):
    operation = ledger.begin(actionRequest.fingerprint, sessionLane.id)

    response = sessionLane.send(actionRequest)
    operation.recordStartResponse(response.status, response.headers)

    if response.status == 204:
        operation.markTransportComplete()
        return verifyBusinessResult(operation, sessionLane)

    if response.status != 202:
        return classifyStartFailure(operation, response)

    location = resolveAndValidateLocation(
        base = response.effectiveRequestUri,
        value = response.headers["Location"],
        allowedOrigin = sessionLane.baseOrigin)

    if location is missing or invalid:
        operation.markIndeterminate("202 without usable Location")
        raise ProtocolError

    operation.storeStatusLocation(location)
    deadline = clock.now + policy.operationTimeout
    delay = policy.initialDelay

    while clock.now < deadline:
        wait(addJitter(delay))
        statusResponse = sessionLane.get(location, timeout = policy.pollTimeout)
        operation.recordPoll(statusResponse.status)

        if statusResponse.status == 202:
            delay = min(policy.maxDelay, policy.nextDelay(delay))
            continue

        if statusResponse.status == 204:
            operation.markTransportComplete()
            return verifyBusinessResult(operation, sessionLane)

        if statusResponse.status == 404:
            operation.markIndeterminate("status not found in this session")
            raise SessionOrOperationNotFound

        operation.markFailed(statusResponse.status, statusResponse.body)
        raise UnexpectedOperationStatus

    operation.markIndeterminate("operation deadline exceeded")
    raise OperationTimeout

The routine deliberately does not resend the action when a poll fails or the deadline expires. Recovery is a separate process with business-aware rules. It also does not reuse the session lane for unrelated calls while polling.

A practical C sharp implementation pattern

In .NET, use one HttpClient and cookie or authorization context for the action and its status requests. The following example is illustrative; adapt authentication, serializers, logging, and retry policy to the target environment.

public async Task PollAcumaticaActionAsync(
    HttpClient client,
    Uri actionUri,
    HttpContent body,
    TimeSpan overallTimeout,
    CancellationToken cancellationToken)
{
    using var start = await client.PostAsync(actionUri, body, cancellationToken);

    if (start.StatusCode == HttpStatusCode.NoContent)
        return;

    if (start.StatusCode != HttpStatusCode.Accepted)
        throw await CreateApiExceptionAsync(start);

    if (start.Headers.Location is null)
        throw new InvalidOperationException(
            "Acumatica returned 202 without a Location header.");

    var statusUri = start.Headers.Location.IsAbsoluteUri
        ? start.Headers.Location
        : new Uri(start.RequestMessage!.RequestUri!, start.Headers.Location);

    if (!SameOrigin(actionUri, statusUri))
        throw new InvalidOperationException("Unexpected status URL origin.");

    var deadline = DateTimeOffset.UtcNow + overallTimeout;
    var delay = TimeSpan.FromSeconds(1);

    while (DateTimeOffset.UtcNow < deadline)
    {
        await Task.Delay(AddJitter(delay), cancellationToken);

        using var status = await client.GetAsync(statusUri, cancellationToken);

        if (status.StatusCode == HttpStatusCode.NoContent)
            return;

        if (status.StatusCode == HttpStatusCode.Accepted)
        {
            delay = TimeSpan.FromSeconds(
                Math.Min(delay.TotalSeconds * 1.5, 10));
            continue;
        }

        throw await CreateApiExceptionAsync(status);
    }

    throw new TimeoutException(
        "The Acumatica operation is still unresolved at the client deadline.");
}

This pattern aligns with the official Acumatica client at a high level: invoke the action, retain Location, query process status, continue on 202, and return on 204.[3][4] A production implementation should add persistent operation records, response-header logging, a session-lane lease, rate-limit handling, and post-completion business verification.

The sample also checks the status URL origin. That is a general defensive measure, not an Acumatica-specific documented requirement. If the deployment legitimately returns another host because of a proxy or public URL configuration, validate the approved host set explicitly rather than disabling the check.

Test matrix for long running integrations

Test against the exact Acumatica build, endpoint version, customizations, authentication mode, proxy path, and representative data volume. The expected outcome below describes client behavior; actual server statuses must be confirmed for each action.

Scenario Server signal or condition Expected client behavior Evidence to retain
Synchronous completion Action returns 204 Skip polling, verify business result Start status, elapsed time, verification fields
Normal asynchronous completion Action returns 202 with Location; polls return 202 then 204 Lease session, poll with delay, stop at 204, verify result Location fingerprint, poll timeline, final read
Missing Location Action returns 202 without usable Location Stop dependent requests; mark protocol error or indeterminate Full response headers, build, endpoint, action
Relative Location Location is a relative URI Resolve against effective request URI and validate origin Raw and resolved values
Immediate completion during first poll Action returns 202; first GET returns 204 Complete without extra delay and verify result One-poll trace
Long but healthy operation Polls return 202 for several intervals Continue within deadline using backoff and jitter Duration, poll count, load context
Client request timeout Network wait ends before response Do not assume server cancellation; enter recovery Exception, elapsed time, request fingerprint
Overall deadline exceeded Status remains 202 beyond policy Stop polling, mark indeterminate, preserve Location Last status, deadline, operation ownership
Session lost Status GET returns 404 or authentication fails Do not construct a new success; recover or escalate Session lane, auth event, status URL
Same-session competing request Another request is sent while operation runs Prevent through lane lease; if conflict occurs, resume polling Conflicting request and preceding 202
409 long-operation conflict Response identifies a long operation on the form Find prior 202/Location; wait and verify before considering one retry Ordered request/response trace
Validation failure Action returns 400 or 422 Surface field errors; do not poll Sanitized error payload
Rate limiting Action or poll returns 429 Apply bounded rate policy; reduce concurrency; preserve operation state Retry timing, pool utilization
Server error during start 5xx before outcome is known Treat replay as potentially unsafe; verify business state first Request hash, response, record snapshot
Server error during poll Status GET returns 5xx or network error Retry status read within policy; do not repeat action Poll attempt and next-delay decision
Worker crash and restart Process stops with saved Location Resume only when session context is valid; otherwise use recovery path Persisted ledger and lease history
Business verification mismatch Poll reaches 204 but record state is unexpected Mark business failure and escalate; do not replay blindly Final status trace and entity payload
Two sessions same document Separate lanes act on one record Enforce document-level coordination and conflict policy Operation keys and document lock history

Run each scenario at least once in a non-production environment. Repeat the normal and long-running cases under representative concurrency. Include custom actions and integrations that call external tax, payment, warehouse, or shipping services, because their timing and side effects can differ from stock examples.

Implementation roadmap

A controlled rollout can be completed in six stages.

1. Inventory actions. List every REST call that invokes an action, generates a report, or processes records. Record the endpoint version, form, method, expected statuses, and business verification fields.

2. Fix response capture. Ensure logs and client wrappers preserve status codes and response headers. Add a hard check for 202 without Location. Remove helpers that discard headers before the integration layer sees them.

3. Add the operation ledger. Persist the operation key, request hash, session lane, timestamps, Location, poll history, terminal transport state, and business verification state. Make updates atomic enough to survive worker restarts.

4. Introduce session lanes. Prevent unrelated work from using a session assigned to a running operation. Bound the pool to licensed and operational capacity. Add queue-time and utilization metrics.

5. Implement and test polling. Start with measured intervals, jitter, a maximum delay, per-request timeouts, and an overall deadline. Exercise every row of the test matrix on the target build.

6. Deploy with observation. Release to a small workload, compare operation durations and conflicts with the prior baseline, and review every timeout or 409. Increase concurrency only when session-lane behavior and business verification remain stable.

The implementation should have a named owner across development and operations. Developers own the state machine and retry safety. Acumatica administrators validate sessions, endpoint versions, permissions, and System Monitor behavior. Functional owners define the business result that must be verified. Infrastructure teams confirm proxy timeouts, DNS, TLS, load-balancer affinity, and logging paths.

Common failure patterns and corrections

Failure: treating 202 as success. The worker sends the next request immediately. Correction: treat 202 as “accepted and still processing”; store Location and poll to 204.

Failure: reading only the body. The integration reports an empty response and loses the status URL. Correction: log status and headers for every call; retrieve Location from the response header.

Failure: sleeping without polling. A fixed five-second pause sometimes works and sometimes does not. Correction: use the server-provided status resource and stop only on a terminal result or deadline.

Failure: assuming timeout cancels Acumatica. The client retries while the original operation continues. Correction: mark the outcome indeterminate and use status or business-state recovery.

Failure: sharing one session across concurrent workers. An unrelated job collides with the active form. Correction: lease bounded session lanes and serialize affected work.

Failure: retrying every 409. The client creates a retry storm or repeats an unsafe action. Correction: classify the conflict, locate the preceding operation, wait for completion, verify state, and retry only when endpoint-specific evidence says it is safe.

Failure: stopping at 204. The transport workflow succeeds, but the document remains in an unexpected state. Correction: read the business object and validate explicit success fields.

Failure: hard-coding the status URL. The integration breaks when endpoint versions or paths change. Correction: consume the returned Location and validate it.

Failure: using a new session for status checks. Polling returns not found or loses the operation context. Correction: preserve the authenticated session from action start through completion.

Failure: calling the behavior a universal product defect. A fix is built around assumptions from one screen or upgrade. Correction: reproduce on the exact endpoint and build, capture the complete request sequence, and distinguish documented behavior from community observations.

Frequently Asked Questions

What does 202 Accepted mean in the Acumatica REST API

For an endpoint action, 202 Accepted means the operation is in progress. The response should include a Location header whose URL can be queried with GET to retrieve the operation status.[1] It does not mean the business action has finished.

Where is the Location URL returned

It is returned in the HTTP response headers of the request that started the asynchronous action. It is not normally a field in the JSON response body. Log headers as well as bodies so the URL is not lost.

How long should an integration poll the Location URL

Use a bounded policy based on measurements for the target action and environment. Acumatica requires a delay between checks, and its official C# client defaults to one second.[2][3] Increase the interval for longer operations, add jitter, and enforce an overall deadline.

Does 204 No Content prove the document reached the expected business state

It proves completion of the documented operation-status workflow and carries no response content.[1][5] The integration should still retrieve the affected entity and verify the fields that define business success.

Should the status request use the same session

Yes. Preserve the same authenticated session and cookie context. The official client uses a persistent HttpClient and cookie container, and its status handling recognizes that an operation may not be found when started in another session.[3]

Why can a later request receive a 409 conflict

One possible cause is that a prior long-running operation is still active on the form in the same session. Current Acumatica documentation says other requests in that session fail until the operation completes, and a recent community case connected that condition with a 409 and long-operation message.[1][7] Inspect the exact response and request timeline before deciding.

Can a client retry the action after a timeout

Not automatically. The server may have accepted the original action even if the client did not receive the response. Check the operation ledger and current business record first. Replay only when the action’s idempotency and endpoint behavior make it safe.

Does every Acumatica PUT return 202 for long work

No universal rule should be assumed. The documented action pattern uses POST, while common record creation and update requests use PUT.[1] Test the exact endpoint, build, configuration, and customization, and log the entire sequence surrounding a conflict.

Can multiple long operations run at the same time

Concurrency may be possible through separate, properly managed sessions, subject to licensing, server capacity, business-record coordination, and endpoint behavior. Do not run concurrent actions through a shared session lane that is already leased to an active operation.

Is the official Acumatica C sharp client enough

The official client provides useful primitives for invoking actions and waiting for completion.[3][4] A production integration still needs persistent operation records, session-pool governance, observability, business verification, security controls, and a recovery policy tailored to its side effects.

Sources

  1. Acumatica Integration Development Guide – Execute an Action That Is Present in an Endpoint
  2. Acumatica Integration Development Guide – Retrieve the Status of the Release Operation
  3. Acumatica official REST API C# client – action invocation and completion polling
  4. Acumatica official REST API C# console example
  5. RFC 9110 – HTTP Semantics
  6. Acumatica Community – Previous operation has not been completed
  7. Acumatica Community – 26 R1 upgrade long-running process error on SO301000

Biz-Tech Services helps teams design, test, and stabilize Acumatica integrations that must remain reliable across upgrades, customizations, and real production workloads. If your integration is losing Location headers, colliding with session-bound operations, or retrying uncertain actions, explore our Acumatica integration services and request an integration reliability review before the next release or volume increase.

Privacy Preference Center