ACA-py instances communicate with each other, for example while establishing a connection, when issuing credentials or when presenting proof. Your controller (your application that talks to ACA-py) can retrieve the data of these events by making calls to the HTTP endpoints. However, ACA-py can also notify your controller when an event occurred. It supports webhooks which allow you to immediately get an update of what happened. In this post I’ll talk you through the webhooks functionality as the documentation seems to be lacking.
Parameter
ACA-py supports a command-line parameter to set up webhooks.
--webhook-url <url#api_key> Send webhooks containing internal state changes to the specified URL. Optional API key to be passed in the request body can be appended using a hash separator #. This is useful for a controller to monitor agent events and respond to those events using the admin API. If not specified, webhooks are not published by the agent.
If you configure the parameter like --webhook-url http://localhost:10000/webhooks, ACA-py will make HTTP POST requests to http://localhost:10000/webhooks/topics/{topic}. This means that you can decide the path at which your controller will receive the webhook calls, so you can make endpoints that receive the calls.
The body of the POST request contains a serialized JSON object that can be deserialized to parse the event.
Topics
Each topic that is used for a webhook is related to a certain event or update of a record in ACA-py. There is documentation available for at least four topics, but after experimenting and searching the code I have found 9 topics.
Out-of-Band Invitation (oob_invitation)
The first webhook you can encounter is the oob_invitation webhook. The event is triggered when you create en invitation using the /out-of-band/create-invitation endpoint.
The only state I have seen for this event is initial. This is probably because at the same time a Connection record is created, and when the invitation is accepted, the Connection record is updated and not the Invitation record. There are no endpoints for retrieving Invitation records.
Example JSON body:
| |
Connection Record Updated (connections)
Whenever a Connection record is updated, a connections webhook will be called. Every state change results in an event. The states for "state" that trigger an event are:
invitationrequestresponseactivecompleted
The values for rfc23_state are:
invitation-sentinvitation-receivedrequest-sentrequest-receivedresponse-sentresponse-receivedcompleted
Example JSON body:
| |
Ping (debug) (ping)
There is a debug option --monitor-ping to receive a webhook call for when a ping message is received. A ping message is originally used in the Aries RFC0160 Connection Protocol to mark a connection as active. However, with Aries RFC0023 this is not required anymore.
Example JSON body:
| |
Basic Message Received (basicmessages)
Basic messages can be sent using the /connections/{id}/send-message endpoint. The messages will not be stored and can only be received by listening to the basicmessages webhook.
Example JSON body:
| |
Credential Exchange Record Updated (issue_credential)
The issue_credential topic is used when an update to a CredentialExchange record occurs. With different states more fields of the event will be filled. The states I’ve seen an event for are:
offer_sentoffer_receivedrequest_sentrequest_receivedcredential_issuedcredential_receivedcredential_acked
Example JSON body:
| |
Issuer Credential Revocation (issuer_cred_rev)
When a credential has been issued, an update is done to the revocation registry. The issuer_cred_rev event contains the details of the update to the revocation registry for the issued credential. I have seen two states:
issuedrevoked
Example JSON body:
| |
Credential Exchange Record V2 Updated (issue_credential_v2_0)
The issue_credential topic is used when an update to a CredentialExchangeV2 record occurs. With different states more fields of the event will be filled. The states I’ve seen an event for are:
offer-sentoffer-receivedrequest-sentrequest-receivedcredential-issueddone
Example JSON body:
| |
Credential Exchange Indy Event (issue_credential_v2_0_indy)
With the introduction of issue-credentials v2, the Indy and DIF parts have been moved out of the credential exchange and do now have their own webhook event.
| |
Credential Exchange DIF Event (issue_credential_v2_0_dif)
With the introduction of issue-credentials v2, the Indy and DIF parts have been moved out of the credential exchange and do now have their own webhook event.
I have yet to receive a DIF event, this will probably work when connecting with an aries-framework-go instance as that supports the DIF SideTree Protocol.
| |
Presentation Exchange Record Updated (present_proof)
When a proof of non-revocation is going on, a PresentationExchange record is updated. With each of the states of the record more fields will be filled in the body. The states that I have seen a webhook event for are:
proposal_sentproposal_receivedrequest_sentrequest_receivedpresentation_sentpresentation_receivedpresentation_ackedverified
Example JSON body:
| |
Revocation Registry Record Updated (revocation_registry)
When a credential definition is created with a revocation registry, a RevocationRegistry record is created. I have seen the following states trigger an event:
initgeneratedpostedactive
Example JSON body:
| |
Problem Report (problem_report)
Problem reports are defined in Aries RFC0035 and are used to report problems for example while issuing credentials or presenting proof. The messages between ACA-py clients contain rich messages with for example a description, which items are a problem, who should retry, a hint for fixing and urls for tracking and escalation. When a problem report is received, for example after calling /issue-credential/records/{cred_ex_id}/problem-report, the webhook will be triggered. There is no endpoint for creating a problem report for presenting proof (yet). Unfortunately, the body of a problem report event is not rich and contains the bare minimum information. The thread id can be used to query the CredentialExchange record, but no mention of the problem report can be found.
Example JSON body:
| |