Skip to navigation

Request verification

Verify that requests sent to your API came through Mitu before processing them.
View as Markdown

When an AI agent uses one of your tools, Mitu sends the corresponding request to your API. Your backend should verify the request before trusting Mitu-specific headers, customer context or payment information.

When you connect your API, Mitu provides a signing secret with the mps_... prefix. Keep this secret on your server and use it only to verify requests sent by Mitu. You do not provide Mitu with your application’s own API credential for this purpose.

Request verification is separate from customer authentication. Verification proves that the request came through Mitu, while customer authentication identifies the customer the AI agent is acting for.

Request headers

Requests sent through Mitu can include the following headers.

HeaderDescription
x-mitu-signatureSignature used to verify that the request came through Mitu.
x-mitu-request-idUnique identifier for the forwarded request. Use it when deduplicating operations with side effects.
x-mitu-amount-chargedAmount associated with a paid request when applicable.
x-mitu-customer-idMitu customer identifier when the request has customer context.
x-mitu-customer-refYour customer reference associated with that customer.
x-mitu-agent-idIdentifier associated with the agent making the request, when available.
authorizationThe customer’s access token when OAuth customer authentication is being used.

Not every request contains every header. Customer headers are only present when a customer has been identified, and payment-specific information is only present where it applies to the payment flow.

Do not use the presence or absence of x-mitu-amount-charged as a substitute for request verification. Always verify the signature first.

Verify the signature

A signed request includes a timestamp and signature value in x-mitu-signature.

x-mitu-signature: t=1757601046,v1=9f3c4a...b2d4

The signature is produced from the signing secret and the signed payload.

HMAC-SHA256(
signing_secret,
"{timestamp}.{request_id}.{amount}.{raw_body}"
)
ComponentValue
timestampThe t value from x-mitu-signature.
request_idThe value of x-mitu-request-id.
amountThe value of x-mitu-amount-charged, or an empty string when it is absent.
raw_bodyThe exact request body bytes received by your server.

The body must be verified in the same form that was signed. Parsing JSON and then serialising it again can change whitespace or field ordering and cause a valid signature to fail.

Node.js example

verify.js
const crypto = require('crypto')
app.use(express.json({
verify: (req, _res, buf) => {
req.rawBody = buf.toString('utf8')
},
}))
function verifyMituRequest(req, secret) {
const header = req.get('x-mitu-signature') || ''
const parts = Object.fromEntries(
header.split(',').map((part) => part.split('=')),
)
const { t, v1 } = parts
if (!t || !v1) {
return false
}
if (Math.abs(Date.now() / 1000 - Number(t)) > 300) {
return false
}
const requestId = req.get('x-mitu-request-id')
const amount = req.get('x-mitu-amount-charged') ?? ''
const signedPayload = `${t}.${requestId}.${amount}.${req.rawBody}`
const expected = crypto
.createHmac('sha256', secret)
.update(signedPayload)
.digest('hex')
if (expected.length !== v1.length) {
return false
}
return crypto.timingSafeEqual(
Buffer.from(v1),
Buffer.from(expected),
)
}

The five-minute window in this example is a policy your own backend enforces. Choose a tolerance appropriate for your infrastructure rather than treating the value as fixed.

Verification rules

Your backend should verify the request before reading Mitu-specific customer or payment context. After verification succeeds, use the request ID to protect operations with side effects from being performed more than once.

Use a timing-safe comparison for signature values and verify against the raw request body rather than reconstructed JSON. A timestamp tolerance should also be enforced so a captured signed request cannot be replayed indefinitely.

Prevent duplicate side effects

A forwarded request can be retried, so endpoints that create or modify state should handle the same x-mitu-request-id more than once without repeating the underlying action.

For example, if a request creates an order, store the relationship between the Mitu request and the order you created:

req_abc123 -> order_8841

If req_abc123 arrives again, return the result associated with order_8841 rather than creating another order.

Persist the idempotency record together with the business operation where possible. This avoids a race where the order is created successfully but the request ID has not yet been recorded when a retry arrives.

Two idempotency directions

x-mitu-request-id helps you deduplicate requests Mitu sends to your API. Idempotency-Key is used when your backend sends supported requests to the Mitu API.

They protect different request directions and should not be treated as the same identifier.

Customer authentication is separate

A verified request can also carry customer identity when the AI agent is acting on behalf of a known customer. If OAuth is being used, the customer’s access token can be forwarded so your backend continues applying its existing authentication and authorisation rules.

The Mitu signature proves where the request came from. The customer access token and your own backend rules determine what that customer is allowed to do.