Prepared with substantial AI assistance for StackEndBox. This article uses the company's public enquiry-controller code and synthetic local tests. It contains no customer payloads or claimed customer outcomes.
A browser sends an enquiry. The server saves it. The response never reaches the browser. What should the interface say?
“Failed, try again” sounds helpful, but it asserts something the browser doesn't know. If the endpoint doesn't provide an idempotency contract, another send can create a second enquiry. A disabled button prevents overlapping clicks in one page instance. It doesn't resolve a lost response or deduplicate work on the server.
That distinction led to a small public form controller with four states: ready, sending, received and uncertain. The useful part is the boundary between the last two.
Define the receipt before styling the success message
For this particular endpoint contract, the controller accepts a response only when the HTTP response is successful, the JSON body says ok: true, and a UUID-shaped reference is present. A UUID shape is a format check, not proof of authenticity. HTTPS, endpoint trust and server behavior still matter.
MDN documents Response.ok as an HTTP 200-299 check. It doesn't inspect your application's business result. Your client must interpret the agreed response body separately.
Source: MDN Response.ok.
Here is the public controller's key decision, with transport construction omitted:
const response = await send(payload);
const body = await response.json();
if (response.ok && body.ok === true &&
/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i.test(body.reference)) {
state = 'received';
return { state, reference: body.reference };
}
The receipt means this application acknowledged the request. It doesn't mean an email notification was delivered, a salesperson read the brief, or the enquiry became a qualified opportunity. Those are later observations.
Treat ambiguity as a real state
The controller enters sending before awaiting the transport. Further submissions are ignored while the state differs from ready. A valid receipt moves it to received, which also prevents another send in the same controller instance.
Rejected JSON parsing, a lost connection, an unsuccessful response with an unknown body, and a success-shaped body without its required reference all produce uncertain. The page doesn't automatically resend. It can tell the user that receipt couldn't be confirmed and offer an alternative contact route without asserting that nothing was stored.
This is deliberately conservative. It trades some convenient retries for avoiding unsupported claims about a non-idempotent collection endpoint. It is not an exactly-once guarantee and does not survive a reload as a durable deduplication mechanism.
Only reopen submission for documented pre-acceptance errors
The implementation recognizes four exact status/body pairs for validation, verification, size and rate-limit rejections. Those return it to ready for a deliberate corrected attempt.
That mapping belongs to this endpoint's contract. Don't copy it to a service whose 429 can arrive after partial processing or whose error body has different semantics. If the client cannot establish that rejection occurred before acceptance, it should preserve the ambiguity.
For endpoints supporting idempotency, use their actual key and retention rules instead. Stripe's API documentation, for example, defines specific behavior for repeated idempotency keys. That contract isn't automatically inherited by an unrelated contact form.
Source: Stripe idempotent requests.
Test the UI's claims, not just its happy path
The existing synthetic test suite exercises concurrent clicks, a saved receipt, lost and malformed responses, success without a reference and deliberate correction after documented pre-acceptance errors. It also checks source categorization and the service-page enquiry paths. Seven tests passed in the local run for this article.
The ambiguous-response test verifies that the state becomes uncertain and a second attempt is ignored. It doesn't prove what a real server stored. The transport is a stub, so the test proves the client's decisions under chosen responses.
Public implementation: https://www.stackendbox.com/seo-assets/service-enquiry.js
Keep engineering acceptance separate from sales reporting
A receipt counter can measure acknowledged submissions. Calling it “clients won” hides everything that follows: fit review, reply, scope, agreement and payment. Even a correctly implemented source category describes an observed referrer, not a proven first touch or AI recommendation.
For a form review, start by writing down the evidence behind each message the user sees. Then ask what the interface does when that evidence is missing. The uncertain state often tells you more about the integration than another green success animation.
Top comments (0)