Idempotency Key

An idempotency key is a unique value generated by the client which the server uses to recognize subsequent retries of the same request. This allows developers to safely retry requests without accidentally performing the same operation twice.

📘

What's a same request?

An API call has two components:

  1. The API request path (ex: /v2/app/coin/createCurrency)
  2. The API request parameters (ex: for createCurrency API call, symbol, name)

Two API calls are considered by MetaKeep to be the same/duplicates if and only if all the following conditions hold true:

  1. The two API calls have the same request path . (ex: two calls to /v2/app/coin/createCurrency)
  2. The two API calls are made by the same developer (i.e., they have the same X-API-KEY header)
  3. The two API calls have the same idempotency key (ex: idempotencyKey = "12ad3" for both API calls)

Note that this means that two API calls satisfying the above conditions, but with different request parameters are still considered identical. For example, the following two API calls are identical-

API Call 1:

curl --request POST \
     --url https://api.galway.metakeep.xyz/v2/app/coin/createCurrency \
     --header 'Accept: application/json' \
     --header 'Content-Type: application/json' \
     --header 'Idempotency-Key: key1' \
     --header 'x-api-key: OfqUxqMiPzYsodWcF9geEW3zjUkHZrhN' \
     --data '
{
     "coin": {
          "name": "USD Coin",
          "symbol": "USDC"
     }
}
'

API Call 2:

curl --request POST \
     --url https://api.galway.metakeep.xyz/v2/app/coin/createCurrency \
     --header 'Accept: application/json' \
     --header 'Content-Type: application/json' \
     --header 'Idempotency-Key: key1' \
     --header 'x-api-key: OfqUxqMiPzYsodWcF9geEW3zjUkHZrhN' \
     --data '
{
     "coin": {
          "name": "Doge Coin",
          "symbol": "DOGE"
     }
}
'

However, as a good practice, client MUST NOT change request parameters between two API calls with same idempotent keys. MetaKeep will throw an error and refuse to acknowledge subsequent API requests with identical Idempotency keys if the request parameters between two API calls change.

The definition, implementation and specification of Idempotency-Key in MetaKeep closely follows the IETF Internet Draft on Idempotency Key

Goal

Safeguard client from network disruptions for an API call. i.e., when an API call from a client is disrupted in transit and the client did not receive a response from the server.

Retries on Queued Transactions

In case of APIs that result in transactions that are to be submitted to Blockchain (ex: createCollection, createCurrency, mint, lock, etc.), if the server responds with a "Queued" status, clients should treat this as a "Final" and successful response. Subsequent retries of this API with the same Idempotency Key will always result in the same "Queued" status, cached from the last execution.

When a cached response is returned by APIs without committing transactions to blockchain, MetaKeep adds Idempotency-Replay: true header for the responses.

Idempotency-Replay: true

To get the transaction status of a blockchain transaction that's been queued by a API, clients should rely on /v2/app/transaction/status API instead, rather than retrying the API which will always only result in a "Queued" status.

Retries on Failure

Idempotency key doesn't help to retry an API call when client receives a definite failure from server. Retrying an API call with same idempotent key which resulted in a failure once before always results in the same failure response which is cached from the last execution.

👍

New ✨ Built-in Resiliency

MetaKeep takes on the burden from developers in orchestrating transactions to completion on underlying blockchains to the best effort. We’re working on bringing powerful new updates to our infrastructure to auto-recover in case of most blockchain failures. What this means for you is retrying of API to re-submit a request to recover from a non-network failure shouldn’t be necessary as the transaction failure, if any, you see would be non-recoverable without external intervention.

❗️

Security and Privacy Advisory

For ease of compliance with GDPR and other consumer privacy laws, MetaKeep strongly recommends developers to not use Personally Identifiable Information (PII) directly as the Idempotency-Key.

Some good ways to generate idempotency keys are:

  1. hash(request parameters)
  2. hash(OrderIdOfUser)
  3. hash(UserEmail+OrderId)
  4. urandom(64) (i.e., a simple random number)
  5. uuid4() (i.e., a UUID random string)
    Here, hash could be a NIST approved Message Digest/One-Way-Hash algorithm depending upon your data.

In case of using PII as Idempotency Key, MetaKeep recommends a hashing algorithm from SHA-2 class or higher such as SHA256 / SHA512 with a salt. For non PII data, such as using request parameters, a weaker but high performance algorithm from SHA-1 class like MD5 suffices.

© Copyright 2024, Passbird Research Inc.