openapi: 3.0.3 info: contact: email: contact@dsb.gov.au name: Data Standards Body url: https://dsb.gov.au/ description: Specifications for resource endpoints applicable to data holders in the Banking sector. license: name: MIT License url: https://opensource.org/licenses/MIT title: CDR Banking Accounts Webhooks API version: 1.36.0 servers: - description: MTLS url: https://mtls.dh.example.com/cds-au/v1 tags: - name: Webhooks description: 'Webhooks provide a mechanism for a configured URL to receive events when transaction activity occurs on Up. You can think of webhooks as being like push notifications for your server-side application. ' paths: /webhooks: get: tags: - Webhooks summary: List webhooks description: 'Retrieve a list of configured webhooks. The returned list is [paginated](#pagination) and can be scrolled by following the `next` and `prev` links where present. Results are ordered oldest first to newest last. ' parameters: - name: page[size] in: query schema: type: integer required: false example: 30 description: 'The number of records to return in each page. ' responses: '200': description: Successful Response content: application/json: schema: $ref: '#/components/schemas/ListWebhooksResponse' x-up:example: type: exampleRequestResponse request: headers: Authorization: Bearer up:demo:sGbPklakZzGRpyN8 pathParameters: {} queryParameters: page[size]: 1 payload: null response: data: - type: webhooks id: 906ffa4f-9ce2-4e24-838b-c0f2ac1941d9 attributes: url: http://example.com/webhook-1 description: Webhook number 1 createdAt: '2024-08-04T12:19:01+10:00' relationships: logs: links: related: https://api.up.com.au/api/v1/webhooks/906ffa4f-9ce2-4e24-838b-c0f2ac1941d9/logs links: self: https://api.up.com.au/api/v1/webhooks/906ffa4f-9ce2-4e24-838b-c0f2ac1941d9 links: prev: null next: https://api.up.com.au/api/v1/webhooks?page%5Bafter%5D=WyIyMDI0LTA4LTA0VDAyOjE5OjAxLjE3MDA3ODAwMFoiLCI5MDZmZmE0Zi05Y2UyLTRlMjQtODM4Yi1jMGYyYWMxOTQxZDkiXQ%3D%3D&page%5Bsize%5D=1 post: tags: - Webhooks summary: Create webhook description: 'Create a new webhook with a given URL. The URL will receive webhook events as JSON-encoded `POST` requests. The URL must respond with a HTTP `200` status on success. There is currently a limit of 10 webhooks at any given time. Once this limit is reached, existing webhooks will need to be deleted before new webhooks can be created. Event delivery is retried with exponential backoff if the URL is unreachable or it does not respond with a `200` status. The response includes a `secretKey` attribute, which is used to sign requests sent to the webhook URL. It will not be returned from any other endpoints within the Up API. If the `secretKey` is lost, simply create a new webhook with the same URL, capture its `secretKey` and then delete the original webhook. See [Handling webhook events](#callback_post_webhookURL) for details on how to process webhook events. It is probably a good idea to test the webhook by [sending it a `PING` event](#post_webhooks_webhookId_ping) after creating it. ' requestBody: content: application/json: schema: $ref: '#/components/schemas/CreateWebhookRequest' responses: '201': description: Created content: application/json: schema: $ref: '#/components/schemas/CreateWebhookResponse' x-up:example: type: exampleRequestResponse request: headers: Authorization: Bearer up:demo:Ai3k0uTDg9UbsMSn Content-Type: application/json pathParameters: {} queryParameters: {} payload: data: attributes: url: http://example.com/webhook description: Example webhook response: data: type: webhooks id: e1dc11ce-c175-4c43-a969-6f8ffc8adc5b attributes: url: http://example.com/webhook description: Example webhook secretKey: EIY19vc8Z7n4Ub58Ex13RxKfsnLyZ6pwwT6wyuv4WboOgvA3xW33BZpkxLDb5hfQ createdAt: '2024-08-06T12:19:01+10:00' relationships: logs: links: related: https://api.up.com.au/api/v1/webhooks/e1dc11ce-c175-4c43-a969-6f8ffc8adc5b/logs links: self: https://api.up.com.au/api/v1/webhooks/e1dc11ce-c175-4c43-a969-6f8ffc8adc5b callbacks: Event: '{webhookURL}': post: summary: Handling webhook events description: "Once you have created a webhook in the Up API, events are sent to the\nwebhook’s configured URL as JSON-encoded `POST` requests. The webhook\nURL must respond with a HTTP `200` status on success.\n\nIt is important that the URL responds in a timely manner. If the URL\ntakes too long to respond (currently 30s), the request will be timed\nout. For this reason it is strongly advised to avoid any heavy\nprocessing before a response has been returned from the URL. A common\nsolution to this problem is to use a message broker such as RabbitMQ\nto do the work asynchronously.\n\nEvent delivery is retried with exponential backoff in the case of any\nnon-`200` response status, if the URL is unreachable, or if the request\nis timed out.\n\nRefer to the `eventType` attribute in order to determine what course of\naction to take when handling the event. The following event types are\ncurrently sent:\n\n**`PING`**\n\nManually triggered by calls to the webhook `ping` endpoint. Used for\ntesting and debugging purposes.\n\n**`TRANSACTION_CREATED`**\n\nTriggered whenever a new transaction is created in Up. This event\nincludes a `transaction` relationship that provides the unique\nidentifier for the transaction and a link to the transaction within the\nUp API. This link should be used to retrieve the complete transaction\ndata.\n\n**`TRANSACTION_SETTLED`**\n\nTriggered whenever a transaction transitions from the `HELD` status to\nthe `SETTLED` status. This event includes a `transaction` relationship\nthat provides the unique identifier for the transaction and a link to\nthe transaction within the Up API. This link should be used to retrieve\nthe complete transaction data.\n\nDue to external factors in banking processes, on rare occasions this\nevent may not be triggered. Separate `TRANSACTION_DELETED` and\n`TRANSACTION_CREATED` events will be received in its place.\n\n**`TRANSACTION_DELETED`**\n\nTriggered whenever a `HELD` transaction is deleted from Up. This\ngenerally occurs for example when a hotel deposit is returned. This\nevent includes a `transaction` relationship that provides the unique\nidentifier for the transaction, however no link is provided to the\ntransaction within the Up API as it no longer exists.\n\n## Securing Webhook Event Handlers\n\nIncoming webhook event requests include a `X-Up-Authenticity-Signature`\nheader, which can be used to verify that the event was sent by Up.\nVerification of the signature requires knowledge of the shared\n`secretKey` that was returned upon creation of the webhook. This key is\nknown only to your application and to Up.\n\nThe verification process involves:\n\n1. Taking the raw, unparsed webhook event request body.\n2. Computing the SHA-256 HMAC signature of the request body, using the\n shared `secretKey`.\n3. Comparing the computed HMAC signature with the value of the\n `X-Up-Authenticity-Signature` header.\n\nIf the computed SHA-256 HMAC signature matches the\n`X-Up-Authenticity-Signature` header, the request is valid.\n\nA few language-specific examples follow.\n\n**Ruby**:\n\nThis example uses the Ruby on Rails framework.\n\n```ruby\nrequire 'openssl'\n\ndef handle_webhook_event\n received_signature =\n request.headers['X-Up-Authenticity-Signature']\n\n signature = OpenSSL::HMAC.hexdigest(\n 'SHA256',\n secret_key,\n request.raw_post,\n )\n\n if Rack::Utils.secure_compare(received_signature, signature)\n # Process webhook event\n end\nend\n```\n\n**PHP**:\n\nThis example uses the Laravel framework.\n\n```php\npublic function handleWebhookEvent(Request $request) {\n $received_signature = $request->header(\n 'X-Up-Authenticity-Signature',\n ''\n );\n $raw_body = $request->getContent();\n $signature = hash_hmac('sha256', $raw_body, $this->secretKey);\n\n if (hash_equals($signature, $received_signature)) {\n // Process webhook event\n }\n}\n```\n\n**Go**:\n\nThis example is in plain Go.\n\n```go\nimport (\n \"crypto/hmac\"\n \"crypto/sha256\"\n \"encoding/hex\"\n \"io\"\n \"net/http\"\n)\n\nfunc handleWebhookEvent(w http.ResponseWriter, r *http.Request) {\n receivedSignature, _ := hex.DecodeString(\n r.Header.Get(\"X-Up-Authenticity-Signature\"),\n )\n\n mac := hmac.New(sha256.New, secretKey)\n io.Copy(mac, r.Body)\n signature := mac.Sum(nil)\n\n if hmac.Equal(signature, receivedSignature)\n // Process webhook event\n }\n}\n```\n\nIf the `secretKey` for a webhook is lost, simply create a new webhook\nwith the same URL, capture the returned `secretKey` and delete the\noriginal webhook.\n" parameters: - name: X-Up-Authenticity-Signature in: header schema: type: string required: false example: 317c0a8ea81df3f53c1d2aef5dcbf60492d0df557197b2990e71daa4a0693364 description: 'The SHA-256 HMAC signature of the raw request body, signed using the `secretKey` of the webhook. ' requestBody: content: application/json: schema: $ref: '#/components/schemas/WebhookEventCallback' responses: '200': description: Successful Response x-up:example: type: examplePayload payload: data: type: webhook-events id: 32e730bd-752d-4ae8-a8e2-bab115c72b6d attributes: eventType: TRANSACTION_CREATED createdAt: '2024-08-06T12:19:02+10:00' relationships: webhook: data: type: webhooks id: 135017b5-2585-4564-ac7d-040043d51667 links: related: https://api.up.com.au/api/v1/webhooks/135017b5-2585-4564-ac7d-040043d51667 transaction: data: type: transactions id: 516f5342-2d25-47b1-a46c-40466ddae069 links: related: https://api.up.com.au/api/v1/transactions/516f5342-2d25-47b1-a46c-40466ddae069 /webhooks/{id}: get: tags: - Webhooks summary: Retrieve webhook description: 'Retrieve a specific webhook by providing its unique identifier. ' parameters: - name: id in: path schema: type: string required: true example: 48984142-bb60-4fd9-8db2-ed72cfc2a0ba description: 'The unique identifier for the webhook. ' responses: '200': description: Successful Response content: application/json: schema: $ref: '#/components/schemas/GetWebhookResponse' x-up:example: type: exampleRequestResponse request: headers: Authorization: Bearer up:demo:Jdn3RtGUFDxYfTkp pathParameters: id: 362f41e4-c750-40ed-8bec-73ecca1e65e1 queryParameters: {} payload: null response: data: type: webhooks id: 362f41e4-c750-40ed-8bec-73ecca1e65e1 attributes: url: http://example.com/webhook-2 description: Webhook number 2 createdAt: '2024-08-05T12:19:03+10:00' relationships: logs: links: related: https://api.up.com.au/api/v1/webhooks/362f41e4-c750-40ed-8bec-73ecca1e65e1/logs links: self: https://api.up.com.au/api/v1/webhooks/362f41e4-c750-40ed-8bec-73ecca1e65e1 delete: tags: - Webhooks summary: Delete webhook description: 'Delete a specific webhook by providing its unique identifier. Once deleted, webhook events will no longer be sent to the configured URL. ' parameters: - name: id in: path schema: type: string required: true example: be530308-60e2-489b-9c73-ab0db6fd132d description: 'The unique identifier for the webhook. ' responses: '204': description: Deleted x-up:example: type: exampleRequestResponse request: headers: Authorization: Bearer up:demo:AICm0MfozWEhnfci pathParameters: id: daf513b4-7c2c-441b-a77c-3b2b63f260f9 queryParameters: {} payload: null response: null /webhooks/{webhookId}/ping: post: tags: - Webhooks summary: Ping webhook description: 'Send a `PING` event to a webhook by providing its unique identifier. This is useful for testing and debugging purposes. The event is delivered asynchronously and its data is returned in the response to this request. ' parameters: - name: webhookId in: path schema: type: string required: true example: ca59a175-79fa-4467-867f-b0cf582ee6bd description: 'The unique identifier for the webhook. ' responses: '201': description: Successful response content: application/json: schema: $ref: '#/components/schemas/WebhookEventCallback' x-up:example: type: exampleRequestResponse request: headers: Authorization: Bearer up:demo:3aQCtgODipPleMHV Content-Type: application/json pathParameters: webhookId: 2649c1f0-b03b-4c21-bb85-331d53644305 queryParameters: {} payload: '' response: data: type: webhook-events id: 973606bb-ad40-426d-9bd8-d76ab70cd038 attributes: eventType: PING createdAt: '2024-08-06T12:19:06+10:00' relationships: webhook: data: type: webhooks id: 2649c1f0-b03b-4c21-bb85-331d53644305 links: related: https://api.up.com.au/api/v1/webhooks/2649c1f0-b03b-4c21-bb85-331d53644305 /webhooks/{webhookId}/logs: get: tags: - Webhooks summary: List webhook logs description: 'Retrieve a list of delivery logs for a webhook by providing its unique identifier. This is useful for analysis and debugging purposes. The returned list is [paginated](#pagination) and can be scrolled by following the `next` and `prev` links where present. Results are ordered newest first to oldest last. Logs may be automatically purged after a period of time. ' parameters: - name: webhookId in: path schema: type: string required: true example: e579c0fe-62e7-47de-b436-4b1dfe110b35 description: 'The unique identifier for the webhook. ' - name: page[size] in: query schema: type: integer required: false example: 30 description: 'The number of records to return in each page. ' responses: '200': description: Successful response content: application/json: schema: $ref: '#/components/schemas/ListWebhookDeliveryLogsResponse' x-up:example: type: exampleRequestResponse request: headers: Authorization: Bearer up:demo:jzQH9GsHMtCmwyr8 pathParameters: webhookId: cce901e8-e10b-4d4d-a615-f1902e4736d4 queryParameters: page[size]: 1 payload: null response: data: - type: webhook-delivery-logs id: 03743de3-1dc8-4893-b1b0-86ab5d613c5b attributes: request: body: '{"data":{"type":"webhook-events","id":"011308c1-861c-4d04-ba85-f867eadf202d","attributes":{"eventType":"TRANSACTION_CREATED","createdAt":"2024-08-05T12:20:07+10:00"},"relationships":{"webhook":{"data":{"type":"webhooks","id":"cce901e8-e10b-4d4d-a615-f1902e4736d4"},"links":{"related":"https://api.up.com.au/api/v1/webhooks/cce901e8-e10b-4d4d-a615-f1902e4736d4"}},"transaction":{"data":{"type":"transactions","id":"169c1684-45c7-41c1-95fa-97082b319e6c"},"links":{"related":"https://api.up.com.au/api/v1/transactions/169c1684-45c7-41c1-95fa-97082b319e6c"}}}}}' response: statusCode: 200 body: '{"ok":true}' deliveryStatus: DELIVERED createdAt: '2024-08-05T12:20:07+10:00' relationships: webhookEvent: data: type: webhook-events id: 011308c1-861c-4d04-ba85-f867eadf202d links: prev: null next: https://api.up.com.au/api/v1/webhooks/cce901e8-e10b-4d4d-a615-f1902e4736d4/logs?page%5Bafter%5D=WyIyMDI0LTA4LTA1VDAyOjIwOjA3Ljk2MjMzODAwMFoiLCIwMzc0M2RlMy0xZGM4LTQ4OTMtYjFiMC04NmFiNWQ2MTNjNWIiXQ%3D%3D&page%5Bsize%5D=1 components: schemas: ListWebhooksResponse: type: object description: 'Successful response to get all webhooks. This returns a paginated list of webhooks, which can be scrolled by following the `prev` and `next` links if present. ' properties: data: type: array items: $ref: '#/components/schemas/WebhookResource' description: 'The list of webhooks returned in this response. ' links: type: object properties: prev: type: string nullable: true description: 'The link to the previous page in the results. If this value is `null` there is no previous page. ' next: type: string nullable: true description: 'The link to the next page in the results. If this value is `null` there is no next page. ' required: - prev - next required: - data - links WebhookResource: type: object description: 'Provides information about a webhook. ' properties: type: type: string description: 'The type of this resource: `webhooks`' id: type: string description: 'The unique identifier for this webhook. ' attributes: type: object properties: url: type: string description: 'The URL that this webhook is configured to `POST` events to. ' description: type: string nullable: true description: 'An optional description that was provided at the time the webhook was created. ' secretKey: type: string description: 'A shared secret key used to sign all webhook events sent to the configured webhook URL. This field is returned only once, upon the initial creation of the webhook. If lost, create a new webhook and delete this webhook. The webhook URL receives a request with a `X-Up-Authenticity-Signature` header, which is the SHA-256 HMAC of the entire raw request body signed using this `secretKey`. It is advised to compute and check this signature to verify the authenticity of requests sent to the webhook URL. See [Handling webhook events](#callback_post_webhookURL) for full details. ' createdAt: type: string format: date-time description: 'The date-time at which this webhook was created. ' required: - url - description - createdAt relationships: type: object properties: logs: type: object properties: links: type: object properties: related: type: string description: 'The link to retrieve the related resource(s) in this relationship. ' required: - related required: - logs links: type: object properties: self: type: string description: 'The canonical link to this resource within the API. ' required: - self required: - type - id - attributes - relationships CreateWebhookRequest: type: object description: 'Request to create a new webhook. This currently only requires a `url` attribute. ' properties: data: description: 'The webhook resource to create. ' allOf: - $ref: '#/components/schemas/WebhookInputResource' required: - data WebhookDeliveryStatusEnum: enum: - DELIVERED - UNDELIVERABLE - BAD_RESPONSE_CODE description: "Specifies the nature of the success or failure of a webhook delivery\nattempt to the subscribed webhook URL. The currently returned values are\ndescribed below:\n\n- **`DELIVERED`**: The event was delivered to the webhook URL\n successfully and a `200` response was received.\n- **`UNDELIVERABLE`**: The webhook URL was not reachable, or timed out.\n- **`BAD_RESPONSE_CODE`**: The event was delivered to the webhook URL\n but a non-`200` response was received.\n" GetWebhookResponse: type: object description: 'Successful response to get a single webhook. ' properties: data: description: 'The webhook returned in this response. ' allOf: - $ref: '#/components/schemas/WebhookResource' required: - data WebhookInputResource: type: object description: 'Represents a webhook specified as request input. ' properties: attributes: type: object properties: url: type: string format: uri description: 'The URL that this webhook should post events to. This must be a valid HTTP or HTTPS URL that does not exceed 300 characters in length. ' description: type: string nullable: true description: 'An optional description for this webhook, up to 64 characters in length. ' required: - url required: - attributes CreateWebhookResponse: type: object description: 'Successful response after creating a webhook. ' properties: data: description: 'The webhook that was created. ' allOf: - $ref: '#/components/schemas/WebhookResource' required: - data ListWebhookDeliveryLogsResponse: type: object description: 'Successful response to get all delivery logs for a webhook. This returns a paginated list of delivery logs, which can be scrolled by following the `next` and `prev` links if present. ' properties: data: type: array items: $ref: '#/components/schemas/WebhookDeliveryLogResource' description: 'The list of delivery logs returned in this response. ' links: type: object properties: prev: type: string nullable: true description: 'The link to the previous page in the results. If this value is `null` there is no previous page. ' next: type: string nullable: true description: 'The link to the next page in the results. If this value is `null` there is no next page. ' required: - prev - next required: - data - links WebhookDeliveryLogResource: type: object description: 'Provides historical webhook event delivery information for analysis and debugging purposes. ' properties: type: type: string description: 'The type of this resource: `webhook-delivery-logs`' id: type: string description: 'The unique identifier for this log entry. ' attributes: type: object properties: request: type: object properties: body: type: string description: 'The payload that was sent in the request body. ' required: - body description: 'Information about the request that was sent to the webhook URL. ' response: type: object properties: statusCode: type: integer description: 'The HTTP status code received in the response. ' body: type: string description: 'The payload that was received in the response body. ' required: - statusCode - body nullable: true description: 'Information about the response that was received from the webhook URL. ' deliveryStatus: description: 'The success or failure status of this delivery attempt. ' allOf: - $ref: '#/components/schemas/WebhookDeliveryStatusEnum' createdAt: type: string format: date-time description: 'The date-time at which this log entry was created. ' required: - request - response - deliveryStatus - createdAt relationships: type: object properties: webhookEvent: type: object properties: data: type: object properties: type: type: string description: 'The type of this resource: `webhook-events`' id: type: string description: 'The unique identifier of the resource within its type. ' required: - type - id required: - data required: - webhookEvent required: - type - id - attributes - relationships WebhookEventCallback: type: object description: 'Asynchronous callback request used for webhook event delivery. ' properties: data: description: 'The webhook event data sent to the subscribed webhook. ' allOf: - $ref: '#/components/schemas/WebhookEventResource' required: - data WebhookEventResource: type: object description: 'Provides the event data used in asynchronous webhook event callbacks to subscribed endpoints. Webhooks events have defined `eventType`s and may optionally relate to other resources within the Up API. ' properties: type: type: string description: 'The type of this resource: `webhook-events`' id: type: string description: 'The unique identifier for this event. This will remain constant across delivery retries. ' attributes: type: object properties: eventType: description: 'The type of this event. This can be used to determine what action to take in response to the event. ' allOf: - $ref: '#/components/schemas/WebhookEventTypeEnum' createdAt: type: string format: date-time description: 'The date-time at which this event was generated. ' required: - eventType - createdAt relationships: type: object properties: webhook: type: object properties: data: type: object properties: type: type: string description: 'The type of this resource: `webhooks`' id: type: string description: 'The unique identifier of the resource within its type. ' required: - type - id links: type: object properties: related: type: string description: 'The link to retrieve the related resource(s) in this relationship. ' required: - related required: - data transaction: type: object properties: data: type: object properties: type: type: string description: 'The type of this resource: `transactions`' id: type: string description: 'The unique identifier of the resource within its type. ' required: - type - id links: type: object properties: related: type: string description: 'The link to retrieve the related resource(s) in this relationship. ' required: - related required: - data required: - webhook required: - type - id - attributes - relationships WebhookEventTypeEnum: enum: - TRANSACTION_CREATED - TRANSACTION_SETTLED - TRANSACTION_DELETED - PING description: 'Specifies the type of a webhook event. This can be used to determine what action to take in response to the event, such as which relationships to expect. '