AF
Medication

API Idempotency and Replay Protection for AFH Medication Workflows

Protect AFH medication APIs with idempotency keys, payload fingerprints, tenant scope, business uniqueness, webhook verification, durable receipts, and replay testing.

August 8, 2026
8 min read

Medication APIs must assume that users double-click, mobile networks retry, queues redeliver, pharmacy webhooks repeat, and offline devices reconnect after uncertainty. Idempotency ensures one intended action creates one logical result. Replay protection ensures an old or captured request cannot be reused to perform a new unauthorized action.

This guide covers software engineering, not medication administration or clinical advice. It was reviewed on August 8, 2026. Providers should test every workflow with controlled data and maintain approved downtime, correction, and reconciliation procedures.

Identify non-idempotent medication actions

Protect operations such as:

  • Create or accept a medication order
  • Generate future schedule opportunities
  • Record administration, refusal, hold, or missed outcome
  • Amend a MAR event
  • Submit or acknowledge a refill request
  • Record pharmacy delivery and receipt
  • Adjust inventory or controlled count
  • Create a medication incident
  • Send a notification or export

A repeated GET is usually a read. A repeated POST can create a second dose, order, receipt, or message unless the server recognizes the same intent.

Give the client's intent a unique key

Generate a cryptographically random key when the user begins the logical submission and reuse it for retries of that same payload. Do not create a new key on every network attempt.

Bind the key to:

  • Authenticated user or trusted integration
  • Facility
  • Operation and endpoint
  • Payload fingerprint
  • Creation and expiration
  • Processing status
  • Final response reference

The IETF Idempotency-Key HTTP field draft describes a unique client value used by a resource to recognize retries. It remains a work in progress, so publish the application's exact behavior rather than implying a final universal standard.

Fingerprint the normalized request

Calculate a server-side fingerprint from the fields that define intent after safe normalization. Exclude transport noise such as request time, but include facility, resident, order or opportunity, outcome, dose context, and source version.

If the same key arrives with a different fingerprint, reject it as key misuse. Do not return the first response for a different resident or dose.

Never put raw medication directions or resident names into the key. Store the protected payload in the application database and only a secure digest in the idempotency record.

Reserve the key atomically

Use a transaction or unique constraint to reserve the key before performing the side effect. States can include processing, succeeded, failed retryable, failed final, and expired.

For a concurrent duplicate:

  • Return processing with a status location, or
  • Return a conflict that tells the client to poll

Do not run both requests and hope the last write wins. Once complete, return the same logical result and resource identifier to later identical retries.

Scope keys to tenant and operation

A key valid for Facility Alpha cannot apply to Facility Beta. A key for recording a refill receipt cannot be reused to accept an order.

Tenant, authenticated principal or integration, operation, and payload fingerprint are part of uniqueness. Validate resident ownership and role again on every request, including retries.

Do not expose whether another tenant used the same random string. Return a generic invalid or unauthorized result.

Protect medication opportunities with stable IDs

Every scheduled dose opportunity should have a stable identifier derived from resident, effective order version, intended local time, and generation rule. Administration events reference that ID.

If two caregivers submit outcomes for the same opportunity, idempotency keys alone are insufficient because they represent different user intents. Enforce one current outcome state with an event history and open a conflict for authorized review.

The offline sync conflict-resolution guide explains stable client event IDs, server receipts, and competing outcome resolution.

Keep idempotency and business uniqueness separate

An idempotency key prevents retry duplication. Business constraints prevent two independently keyed requests from violating the model.

Examples:

  • One accepted version for the same pharmacy submission
  • One generated opportunity per order version and intended time
  • One inventory movement per receipt line
  • One current outcome per scheduled opportunity
  • One active facility relationship for a bounded access exchange

Use both protections. A double-click may share a key; two tabs might not.

Secure webhook replays

For pharmacy and delivery webhooks:

  • Verify cryptographic signature
  • Validate timestamp within a bounded window
  • Check provider event ID
  • Bind the endpoint to the expected integration account
  • Store raw-body digest if required for verification
  • Process the business event idempotently
  • Reject revoked secrets

Do not rely on source IP alone. A valid repeated webhook should return the prior processing result without applying the order or delivery twice.

Store secret and signature material outside general logs.

Protect against captured request replay

For sensitive access-code exchange, invitation acceptance, or pharmacy relationship grants, use single-use tokens with short expiration and atomic consumption. Idempotency may return the original success to the same authenticated recipient, but it must not grant access to a new session or identity.

For authenticated writes, require fresh valid authorization and appropriate anti-CSRF controls. An idempotency key is not an authentication secret.

Bind high-risk requests to current session, tenant, purpose, and payload. Reject expired or already consumed authorization even when the body is identical.

Define retry behavior by failure point

Distinguish:

  • Rejected before reservation
  • Reserved but not started
  • Side effect committed but response lost
  • Partial downstream processing
  • Final validation failure
  • Temporary dependency failure

The most dangerous case is committed side effect with lost response. The retry must find the prior success and return its receipt.

For partial work, use a transaction, outbox, or resumable state machine. Do not mark overall success while schedule generation or inventory update remains missing.

Keep a durable response receipt

Return:

  • Idempotency key reference or request ID
  • Created resource ID
  • Current status
  • Server acceptance time
  • Order or event version
  • Downstream processing status
  • Polling location when asynchronous

The client stores the receipt before clearing its pending state. If it crashes, it can query by its original key.

Do not require the caregiver to recreate an administration because the success message was lost.

Choose expiration carefully

Retain idempotency records long enough to cover mobile retries, offline synchronization, webhook redelivery, and delayed client recovery. Different operations may need different windows.

After expiration, business uniqueness still prevents dangerous duplication. A stable medication opportunity cannot accept an unrelated second outcome silently just because the key record aged out.

Document the expiration contract for integration partners. Clean up idempotency payload references under the protected retention process.

Make the interface reflect uncertainty

After submission, show sending, processing, confirmed, needs review, or failed. Do not show success until the server receipt is durable.

Disable only duplicate activation of the same action while allowing navigation where safe. If the connection fails, keep the pending record and offer retry using the same key.

When the server returns an existing success, tell the user the record was already confirmed rather than displaying a frightening duplicate error.

Monitor duplicates and misuse

Track:

  • Retries returning prior success
  • Concurrent duplicates
  • Same key with different fingerprint
  • Duplicate business constraints prevented
  • Webhook signature or timestamp failures
  • Expired-token replay attempts
  • Side-effect/receipt mismatches
  • Processing keys stuck beyond timeout
  • Cross-tenant key misuse

Use opaque identifiers and never log raw tokens, signatures, resident names, or medication payloads.

Reconcile successful idempotency records against actual orders, events, schedules, receipts, and inventory movements.

Test every replay path

Use demonstration medication data to verify:

  1. Double-click sends the same key twice.
  2. Response is lost after commit.
  3. Concurrent identical requests arrive.
  4. Same key carries a changed payload.
  5. Two tabs use different keys for one opportunity.
  6. Offline event retries after several hours.
  7. Pharmacy webhook delivers twice.
  8. Valid signature has an expired timestamp.
  9. Revoked webhook secret is rejected.
  10. Receipt creates one inventory movement.
  11. Order acceptance creates one schedule.
  12. Partial schedule generation resumes.
  13. Key reused across facilities is denied.
  14. Single-use access token is replayed.
  15. Client crash recovers the prior receipt.
  16. Cleanup occurs without enabling business duplication.

Inspect both API responses and database side effects. A clean interface can hide duplicate inventory or schedule records.

Frequently asked questions

Is disabling the Submit button enough?

No. Networks, queues, tabs, webhooks, and attackers bypass interface controls. Enforce idempotency and business uniqueness on the server.

Can the same key be used with changed medication data?

No. Bind it to a payload fingerprint and reject reuse for different intent.

Is an idempotency key a security token?

No. Authenticate and authorize every request and apply CSRF or signature protections. The key only identifies retry intent.

What if the server succeeded but the client saw a timeout?

The client retries with the same key; the server returns the original resource and receipt instead of performing the action again.

Do idempotency records need permanent retention?

Not necessarily. Retain them for the documented retry window, while durable business constraints and event IDs continue preventing unsafe duplication.

Make one intended action produce one accountable result

Reliable medication APIs combine idempotency keys, payload fingerprints, atomic reservation, tenant scope, business uniqueness, webhook verification, durable receipts, and reconciliation.

Explore AFH Manager to test double submissions, offline retries, pharmacy webhooks, order acceptance, medication outcomes, inventory receipts, and replay denial with demonstration records.

MedicationIdempotencyReplayProtectionWorkflows
Share
AF

AFH Manager Editorial Team

Editorial standards

Practical educational guidance based on public sources and Adult Family Home workflow research. It does not replace medical, legal, or regulatory advice.

Ready to Streamline Your AFH?

Join hundreds of AFH professionals using AFH Manager to simplify resident care, medication tracking, and compliance documentation.

AFH Assistant

Ask me anything about AFH Manager

Let's get started!

Please tell us a bit about yourself so we can help you better.

We'll use this info to follow up and help you better.

Powered by KGlabs