Skip to main content

Idempotency

Every analysis request requires an Idempotency-Key. One key represents one logical message submission.

Key contract

Use 8–128 ASCII characters matching:

^[A-Za-z0-9][A-Za-z0-9._:-]{7,127}$

A UUID with an integration prefix is suitable:

mailgw-0b8c29c8-491a-4a8d-a832-58e5417e065f

The key is not the API credential. Do not include an address, subject, message ID, or other personal data in it, and do not reuse it indefinitely.

Observable behavior

  • Create a new key for every new logical submission.
  • Read the EML bytes once and retain that immutable buffer for all attempts.
  • Reuse the same key and exactly the same bytes after a network failure, client timeout, or retryable response.
  • The same scoped key and same bytes can replay the stored public response for 24 hours.
  • The same key with different bytes returns 409 idempotency_conflict; do not retry that combination.
  • A completed replay does not account the same operation twice.
  • A client timeout does not prove that Hermes did not execute the operation.
  • 503 analysis_outcome_unknown means Hermes cannot safely confirm the original outcome. Keep the same key; never create another key automatically to bypass it.

Idempotency is scoped to the authenticated credential's organization, customer, and environment. Callers never select that scope in the request.

Retry decisions

OutcomeRetry?Same key and bytes?DelayIf it persists
Network error or client timeoutYes, boundedYesExponential backoff with jitterStop and contact support; explain that no terminal response arrived
408 request_body_timeoutYes, boundedYesExponential backoff with jitterCheck upload/network behavior, then provide request_id
409 idempotency_conflictNoNot applicableNoneRecover the original bytes or start a genuinely new operation with a new key
429Yes, boundedYesUse Retry-After when present; otherwise backoff with jitterReduce concurrency and provide request_id
500 internal_errorYes, boundedYesBackoff with jitterStop; provide request_id without assuming another retry will succeed
503 idempotency_in_progressYes, boundedYesUse Retry-AfterStop and provide request_id
503 analysis_outcome_unknownYes, later and boundedYesUse Retry-After when presentDo not create a new key; contact support
Other 503Yes, boundedYesUse Retry-After when present; otherwise backoff with jitterStop and provide request_id
Other 4xxNo automatic retryPreserve for diagnosisCorrect the request or authorization firstContact support if the correction is unclear

Hermes sends Retry-After only when it can calculate a useful interval. Its absence is not permission to retry immediately.

Persist your own operation state

The 24-hour replay window supports recovery; it is not long-term result storage. Persist the key, terminal status, analysis ID, and request ID in your own authorized system.