Skip to content

Register Webhook

Endpoints to create, list, and remove notification webhooks.


Create Webhook

POST /api/external/webhooks

Headers

HeaderTypeRequiredDescription
AuthorizationStringYesApiKey {client_id}:{client_secret}
Content-TypeStringYesapplication/json
hmacStringYesHMAC-SHA512 signature of the body (learn more)

Request Body

FieldTypeRequiredDefaultDescription
urlStringYes--URL to receive notifications (HTTPS by default)
eventsArrayYes--List of events to subscribe to. Must be a non-empty array with at least one valid event from the table below. Omitting the field returns 400 {"errors": {"events": ["can't be blank"]}}.
secretStringNoauto-generatedKey for HMAC-SHA256 signing of deliveries. If omitted, a random value is auto-generated.
descriptionStringNonullFree description of the webhook for internal identification
allow_insecureBooleanNofalseAllow HTTP (non-HTTPS) URLs. Data security is the client's responsibility.

Available events (PIX, TEF between Minha Konta accounts, and operational webhook test):

EventStatus bodyDescriptionDispatch
pix.charge.createdcreatedQR code generated or cash-in initiatedActive
pix.charge.paidpaidPIX received and settledActive
pix.charge.expiredexpiredQR code expired without paymentActive
pix.charge.cancelledcancelledQR code cancelled before paymentRegistered, not yet dispatched
pix.payout.queuedqueuedPIX send queued by operational limitActive
pix.payout.processingprocessingPIX sent, awaiting confirmationActive
pix.payout.confirmedsettledPIX sent and confirmed (terminal)Active
pix.payout.failedrejectedPIX send rejected (terminal)Active
pix.payout.returnedreturnedSent PIX was returnedActive
pix.refund.requestedrequestedRefund request received (BACEN infraction); preventive block created on the client balanceActive
pix.refund.completedsettled / completedDefense analysis finalized and refund executed (or released)Active
pix.return.receivedsettledPIX return received (credit)Active
pix.infraction.createdACKNOWLEDGEDPIX infraction reported by counterparty via BACEN DICTActive
pix.infraction.resolvedCLOSED / CANCELLEDInfraction resolved by final decision or counterparty cancellationActive
pix.infraction.defense_submitteddefense_submittedDefense submitted by the merchantActive
tef.transfer.sentsettledTEF between Minha Konta accounts settled for the origin accountActive
tef.transfer.receivedsettledTEF between Minha Konta accounts settled for the destination accountActive
tef.transfer.failedfailedTEF between Minha Konta accounts rejected or not settledActive
webhook.testtestManual test. Available only via Admin/Merchant portal - there is no External API endpoint to dispatchManual dispatch

pix.charge.cancelled is not yet dispatched

The event can be subscribed to, but there is no public QR code cancellation flow currently dispatching this notification type. You may include it in the events array - the API accepts it - but no notification will arrive at your endpoint until the flow is made available.

Any event outside this table is rejected

When creating a webhook, each requested event is validated against the public list of supported events. Unknown events (boleto.paid, account.created, sta.file.*, etc.) return 400 with error events: contains invalid events: ....

Payloads for each event

Full payload examples for each event are in Webhook Payloads.

Example

bash
BODY='{"url":"https://yoursite.com/webhook","events":["pix.charge.paid","pix.payout.confirmed"]}'
HMAC=$(echo -n "$BODY" | openssl dgst -sha512 -hmac "$CLIENT_SECRET" | awk '{print $2}')

curl -X POST https://api.minhakonta.com/api/external/webhooks \
  -H "Authorization: ApiKey $CLIENT_ID:$CLIENT_SECRET" \
  -H "Content-Type: application/json" \
  -H "hmac: $HMAC" \
  -d "$BODY"

Success Response (201)

json
{
  "worked": true,
  "id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
  "url": "https://yoursite.com/webhook",
  "events": ["pix.charge.paid", "pix.payout.confirmed"],
  "secret": "a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4",
  "description": null,
  "is_active": true,
  "created_at": "2026-03-07T15:30:00Z"
}

Format of id

The webhook id is a canonical UUID v4 (36 characters with hyphens). Use this value directly in DELETE /api/external/webhooks/:id.

Error Response (422)

json
{
  "worked": false,
  "detail": "URL deve utilizar HTTPS"
}

HTTPS only by default

The webhook URL must use HTTPS. URLs with HTTP will be rejected unless allow_insecure: true is sent on registration.

Important - Webhook Secret

The secret field returned in the registration response is the key used to sign webhook deliveries (HMAC-SHA256). Store this value securely as soon as you receive it - it is what validates that a notification actually came from Minha Konta.

Do NOT confuse with client_secret:

  • client_secret = authentication for your API requests (Authorization header)
  • Webhook secret = verification of received delivery signatures (X-Minha Konta-Signature header)

If you do not send the secret field at registration, a random value will be auto-generated and returned in the response.

See Webhook Validation for examples of how to verify the signature.

Retrieving the secret later

The secret is returned both in POST /api/external/webhooks (creation) and in GET /api/external/webhooks and GET /api/external/webhooks/:id (query). If you lose the value, simply query the webhook again via GET.

In a future version this behavior may be restricted (display only on creation); we recommend storing the secret in a managed secret (vault, SSM, etc.) at registration time.

HTTP URLs

By default, webhooks require HTTPS to guarantee data security in transit. To use HTTP, send allow_insecure: true on registration.

Attention

HTTP URLs transmit data without encryption. The security and confidentiality of the information exchanged is the client's full responsibility. Minha Konta performs webhook delivery normally but assumes no liability for interception or data leakage on unencrypted connections.

Private URLs are always blocked

Even with allow_insecure: true, URLs pointing to private/internal addresses are rejected:

  • localhost / 127.x.x.x
  • RFC1918: 10.x.x.x, 192.168.x.x, 172.16-31.x.x
  • Internal TLDs: .local, .internal

Webhooks must point to public URLs accessible over the internet.


List Webhooks

GET /api/external/webhooks

Headers

HeaderTypeRequiredDescription
AuthorizationStringYesApiKey {client_id}:{client_secret}

Example

bash
curl -X GET https://api.minhakonta.com/api/external/webhooks \
  -H "Authorization: ApiKey $CLIENT_ID:$CLIENT_SECRET"

Success Response (200)

Returns an array of objects (not wrapped in {"worked": true}). Each item contains the same fields as registration, including secret.

json
[
  {
    "id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
    "url": "https://yoursite.com/webhook",
    "events": ["pix.charge.paid", "pix.payout.confirmed"],
    "description": null,
    "account_id": 10014,
    "is_active": true,
    "allow_insecure": false,
    "status": "active",
    "secret": "a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4",
    "created_at": "2026-03-07T15:30:00",
    "updated_at": "2026-03-07T15:30:00"
  }
]
FieldTypeDescription
idstring (UUID)Webhook identifier
urlstringDestination URL
eventsarraySubscribed events
descriptionstring or nullOptional description
account_idinteger or nullAssociated account. null = webhook global for the API key (if supported)
is_activebooleanfalse = webhook paused, no delivery is dispatched
allow_insecurebooleantrue = HTTP URLs accepted
statusstringDerived from is_active - "active" or "inactive"
secretstringHMAC-SHA256 key used to sign deliveries. Returned on LIST to allow recovery if the client lost the original value
created_at / updated_atstring ISO 8601Timestamps in UTC, format NaiveDateTime (without Z suffix, e.g., "2026-03-07T15:30:00"). Different from other date fields in webhook payloads (paid_at, returned_at, expired_at) which use DateTime ISO 8601 with trailing Z. Always assume UTC for the webhook object fields

Remove Webhook

DELETE /api/external/webhooks/:id

Headers

HeaderTypeRequiredDescription
AuthorizationStringYesApiKey {client_id}:{client_secret}

Path Parameters

ParameterTypeRequiredDescription
idString (UUID)YesWebhook ID (UUID v4 returned by the creation endpoint)

Example

bash
curl -X DELETE https://api.minhakonta.com/api/external/webhooks/a1b2c3d4-e5f6-7890-abcd-ef1234567890 \
  -H "Authorization: ApiKey $CLIENT_ID:$CLIENT_SECRET"

Success Response (204)

HTTP 204 No Content - empty body. The webhook was successfully removed; no pending delivery will be dispatched.

First call: 204. Subsequent: 404

The first successful call returns 204 No Content. Subsequent calls with the same id return 404 { "errors": { "not_found": "webhook not found" } } - the webhook was already removed. This is not strict HTTP idempotency (where every call would return 204) - it is the standard DELETE behavior when the resource ceases to exist. Write your integration to accept both 204 and 404 as "the webhook is no longer active".

Error Response (400)

Invalid id format (not UUID):

json
{
  "errors": {
    "bad_request": "id must be a valid UUID"
  }
}

Error Response (404)

Webhook does not exist or does not belong to your account:

json
{
  "errors": {
    "not_found": "webhook not found"
  }
}

Minha Konta Instituição de Pagamento - ISPB 39929224