> ## Documentation Index
> Fetch the complete documentation index at: https://docs.ebury.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Webhook notifications

Practically speaking, a webhook is a POST request to a url of your choice, triggered by an internal event of a remote service.
The benefit of webhooks is to receive desired type of notifications to your systems from remote services without regular polling.

The Ebury Events System Webhooks API allows you to add your subscriptions (i.e. HTTP endpoints) to receive Events Systems' notifications.

## Usage

**1. GraphQL query**

```graphql theme={null}
{
    subscriptions {
        nodes {
            clientId
            contactId
        }
    }
}
```

**2. Corresponding HTTP request**

```http theme={null}
POST /webhooks/graphql HTTP/1.1
Authorization: Bearer $access_token
Content-Type: application/json
X-Client-ID: $client_id

{
  "query": "{ subscriptions { nodes { clientId contactId } } }"
  "variables": {}
}
```

The Webhooks API is using [GraphQL](https://graphql.org/).

This means that your queries will look like this:

1. in GraphQL (example #1)
2. as an HTTP POST request (example #2)

Your already existing infrastructure can be used to send HTTP requests as usual, and the response will be serialized as JSON data.
In addition, detailed data schema information is also provided, helpful to improve tooling on your side.

## Notification History

Every notification attempt is stored on our side.
On top of the notification details, we also store the status code, headers and body returned by your subscription in response.

Notifications history, including failed attempts will be available for you to review anytime.

## Authentication

Authentication is managed as usual for Ebury API services.
You have to provide `Authorization: Bearer $access_token` as described in the [Authentication](/api/authentication) chapter.

Please note that the `client_id` parameter is still mandatory. However it could be provided in two different ways.

1. as a query parameter (as usual)
2. as an `X-Client-ID` HTTP header field

We are allowing for this second option in order to be more respectful with the GraphQL standards (see: [Webhook Examples](#webhook-examples)).

## GraphQL: differences from REST

You can think of the Webhooks API as any traditional (REST) API. However having said that, if you want to make use of a better user experience you may want to consider the following resources:

* The Webhooks API is following the [GraphQL specs](http://spec.graphql.org/June2018/)
* Each endpoint supports [Schema Introspection](http://spec.graphql.org/June2018/#sec-Introspection). This allows you to validate your queries, determine the type of result data, etc.
* Pagination goes according to the [Relay Cursors Connections Specification](https://relay.dev/graphql/connections.htm). (Consistent pagination and ordering via cursors.)

The Webhooks API has one single endpoint (`/webhooks/graphql`), supporting uniquely POST requests. Due to this reason, interacting with the API is a bit different from what you may be used to.

(The [Webhook Examples](#webhook-examples) section should help you to get used to required payloads.)

### Retrieving information

```json theme={null}
{
  "query": "{\n    clientId\n    contactId\n}",
  "variables": {}
}
```

Instead of GET queries, now we will have to send a POST request when aiming to retrieve information.

The JSON payload requires two fields

* `query`: the query as a string
* `variables` (optional): further information to be passed with the request, as a JSON dictionary.

### Add/modify/delete

```json theme={null}
{
  "query": "mutation deleteSubscription($id: UUID!){deleteSubscription(input: {id: $id }) {}}",
  "variables": {
    "id": "c9f8f293-3391-4cc7-9a97-cb0e26d901e9"
  }
}
```

GraphQL allows for data modifications via internal objects called `mutations`, referring to GraphQL functions on the Webhooks API database.

A number of mutation functions belong to each data structure, one for each data manipulation action (create, update, delete).

Your HTTP request has to refer to the one specific to your needs.
The JSON payload will require

* `query` field
  * embedding the `mutation` function signature
    * embedding the mutation function data
* `variables`: potential variables

### Error Reporting

The returned HTTP response may (or may not) contain an `error` entry. This is a non-empty list of errors, thus **only** shipped when errors were encountered.

Each entry in the `errors` list is a map, containing a `message` string field. Please note that the message is intended for the *developer*.
(see [GraphQL Errors Specification](http://spec.graphql.org/June2018/#sec-Errors)).

## Great developer tools

<Note>
  This feature is not yet fully available in the initial Webhooks API release. However you may find it useful despite the limited functionality.
</Note>

As a part of the Webhooks API, an interactive [GraphiQL](https://github.com/graphql/graphiql) interface is available (at the Webhooks API url root), which facilitates the construction of request payloads enormously.

It allows you to write and execute your queries live, get a description of functionalities available for the schema (with detailed help messages on each),
provides embedded text completion for writing syntactically valid queries etc.

Especially in case you are new to GraphQL we strongly recommend you to take a look at this feature. It allows for an easy and natural introduction to the GraphQL syntax.
It is extremely helpful, intuitive, self-explaining... and fun.

## Securing your webhooks

Ebury will put a signature in every HTTP request sent so you can verify if you can trust the payload. The header `X-Ebury-Signature` will contain the sha3 HMAC hexdigest of the URL concatenated with the body payload. The `secret` to be used as key in the HMAC computation can be stored and retrieved alongside other fields of the subscription. If you don't set a `secret`, the empty string will be used as a key.

For an url `url`, body `body` and a secret `secret`, you can expect a header `X-Ebury-Signature` to be exactly `sha3-256=52cecc9451d6279c3ef1d345c76edb320782203f876d19396fc9baeafbcbf81f`.

## Webhook Request Headers

Every webhook request sent by Ebury includes the following headers:

**Headers**

<ParamField header="X-Ebury-Client-Id" type="string">
  Identifies which client is the stakeholder of the webhook call
</ParamField>

<ParamField header="X-Ebury-Signature" type="string">
  Contains the sha3 HMAC hexdigest for payload verification
</ParamField>

<ParamField header="X-Ebury-Webhook" type="string">
  Identifies the type of notification being received
</ParamField>

<ParamField header="X-Ebury-Notification-Id" type="string">
  Idempotency key for the notification
</ParamField>

<ParamField header="X-Ebury-Delivery-Id" type="string">
  Randomly generated UUID for each request
</ParamField>

<ParamField header="X-Ebury-Attempt-Number" type="string">
  Counter for the number of attempts
</ParamField>

<ParamField header="Content-Type" type="string">
  Set to `application/json`
</ParamField>

### Idempotency Headers

The idempotency headers allow clients to differentiate between retries of the same notification and similar independent notifications:

* **X-Ebury-Notification-Id**: This is the idempotency key that remains constant for all attempts of the same notification
* **X-Ebury-Delivery-Id**: A unique UUID generated for each individual request attempt
* **X-Ebury-Attempt-Number**: An incremental counter showing which attempt this is (starts at 1)

### Custom Headers

In order to help with cases where the server that is receiving the Ebury notifications expect certain headers on the request, the subscriptions can be created with `extraHeaders`. The `extraHeaders` are going to define the static name and value of custom headers that will be added to all webhook notifications that go to the subscription URL.

* There is a limit of 5 custom headers per subscription.
* The header name cannot be longer than 128 characters and needs to start with `x-`.
* The header value cannot be longer than 256 characters.

The `extraHeaders` syntax on the create subscription GraphQL request works as follows:

```
extraHeaders: [
    {
        name: "x-custom-header",
        value: "myheadervalue"
    },
    {
        name: "x-another-header",
        value: "anothervalue"
    }
]
```

## Webhooks Traceability

To simplify the developer experience, a contact can subscribe several clients to the same url.
If this is the case, you will need that the webhook receiver can identify which client is the stakeholder of a particular call.
You can do that by checking the value of the header `X-Ebury-Client-Id`.

## Webhooks Types

Ebury supports several types of events, which you can see in the table below. You can subscribe to one specific event or to
all of them.
In every webhook POST call, you will receive a JSON payload as body.
You can identify which type of notification you are receiving, by checking the `X-Ebury-Webhook` header.

### Query all types

You can get a list of all currently supported types by using the custom function webhookTypes.

```graphql theme={null}
{
    webhookTypes
}
```

```http theme={null}
POST /webhooks/graphql HTTP/1.1
Authorization: Bearer $access_token
Content-Type: application/json
X-Client-ID: $client_id

{
  "query": "{\n    webhookTypes\n}",
  "variables": {}
}
```

```json Response theme={null}
HTTP/1.1 200 OK
Server: nginx/1.13.10
Date: Thu, 10 Sep 2020 19:03:27 GMT
Content-Type: application/json; charset=utf-8
Content-Length: 196
Connection: close
X-GraphQL-Event-Stream: /graphql/stream

{
  "data": {
    "webhookTypes": [
      "TRADE_STATUS_CHANGE",
      "PAYMENT_STATUS_CHANGE",
      "CREDIT_INCOMING_TRANSACTION",
      "CREDIT_MARGIN_TRANSACTION",
      "CREDIT_PAYMENT_RETURNED_TRANSACTION",
      "CREDIT_TRANSACTION",
      "DEBIT_TRANSACTION",
      "ONBOARDING_STATUS_CHANGE"
    ]
  }
}
```

### List of types

This is the current (growing) list of notifications you can receive using the Webhooks API.

| Notification | `X-Ebury-Webhook` | Type |
| - | - | - |
| Status change on Trades created by the client. | [`TradeStatusChange`](#tradestatuschange) | `TRADE_STATUS_CHANGE` |
| Status change on Payments created by the client. | [`PaymentStatusChange`](#paymentstatuschange) | `PAYMENT_STATUS_CHANGE` |
| Incoming funds into client's account. | [`CreditIncomingTransaction`](#credittransaction) | `CREDIT_INCOMING_TRANSACTION` |
| Margin credited back into client's account. | [`CreditMarginTransaction`](#credittransaction) | `CREDIT_MARGIN_TRANSACTION` |
| Returns of the payments the client initiated. | [`CreditPaymentReturnedTransaction`](#credittransaction) | `CREDIT_PAYMENT_RETURNED_TRANSACTION` |
| Credit is made to a client's account. | [`CreditTransaction`](#credittransaction) | `CREDIT_TRANSACTION` |
| Debit is made to a client's account. | [`DebitTransaction`](#credittransaction) | `DEBIT_TRANSACTION` |
| Status change when onboarding new client | [`OnboardingStatusChange`](#onboardingstatuschange) | `ONBOARDING_STATUS_CHANGE` |

### TradeStatusChange

```json theme={null}
{
    "data":
    [
      {
        "beneficiaries": [],
        "rate_symbol": "EURGBP",
        "trade_id": "EBPOTR002781",
        "buy_currency": "EUR",
        "fee_amount": 0.0,
        "parent_trade_id": null,
        "status": "Created",
        "trade_receipt": "/documents?type=tr&id=EBPOTR002781&client_id=EBPCLI00004",
        "rate": 0.935057,
        "order_date": "2020-06-29",
        "maturity_date": "2020-06-29T20:00:00.00Z",
        "sell_currency": "GBP",
        "reference": "",
        "fee_currency": "GBP",
        "synthetic": false,
        "sell_amount": 935.06,
        "trade_type": "spot",
        "buy_amount": 1000.0
      }
    ]
}
```

This model is a representation of the webhook for a status change on a trade.

**Fields**

<ResponseField name="data" type="array">
  Always present. A list of [BookedTrade](/api/trade-models#bookedtrade)
</ResponseField>

### PaymentStatusChange

```json theme={null}
{
    "data":
    [
      {
        "account_number": "",
        "amount": 6.02,
        "approvals_workflow": {
            "authorisations": [],
            "contact_authorisation_actions": {},
            "n_eyes_plus_status": "Awaiting approval",
        },
        "authorisation_workflow": "4-eyes",
        "authorised_by": null,
        "authorised_date": null,
        "bank_identifier": "",
        "beneficiary_name": "Homer Simpsons S.L.",
        "cancelled_by": null,
        "cancelled_date": null,
        "contact_id": "EBPCON00005",
        "created_date": "2020-07-14",
        "fee_amount": 12.85,
        "fee_currency": "EUR",
        "iban": "GB81KMWJ48036895317360",
        "invoice_required": false,
        "payment_currency": "GBP",
        "payment_date": "2020-07-15",
        "payment_id": "PI02488",
        "payment_instruction": "/documents?type=pi&id=PI02488&client_id=EBPCLI00004",
        "payment_receipt": "/documents?type=pr&id=PI02488&client_id=EBPCLI00004",
        "reference": "Development services",
        "rejected_by": null,
        "rejected_date": null,
        "status": "Validating beneficiary information",
        "swift_code": "GBGBGBGB",
        "trade_id": "EBPOTR002772"
      },
    ],
    "payment_webhook_status": ["CREATED"]
}
```

This model is a representation of the webhook for a status change for a payment.

**Fields**

<ResponseField name="data" type="array">
  Always present. A list of [Payment](/api/payment-models#payment)
</ResponseField>

<ResponseField name="payment_webhook_status" type="array">
  Always present. A list of [PaymentWebhookStatus](#payment-webhook-status)
</ResponseField>

### CreditTransaction

```json theme={null}
{
    "data":
    [
        {
          "account_id": "c18a42df-6652-d462-351b-0485a6d6bc16",
          "additional_transaction_information": "EURGBP 0.876804 - other",
          "amount": {
              "amount": "100.00",
              "currency": "EUR"
          },
          "balance": {
              "amount": {
                  "amount": "50212.85",
                  "currency": "EUR"
              },
              "type": "InterimAvailable",
              "credit_debit_indicator": "Credit"
          },
          "booking_datetime": "2019-11-11T20:37:30.598",
          "credit_debit_indicator": "Credit",
          "status": "Booked",
          "transaction_id": "3ae5b450-1e1a-b116-1fde-3cb4f0353e16",
          "transaction_information": "Bought EUR EBPOTR002772",
          "transaction_reference": "EBPOTR002772",
          "value_datetime": "2019-11-11T20:37:30.598",
          "creditor_name": "Jorge Chapa",
          "creditor_account": {
              "account_name": "EBURY OFFICE ACC CHF",
              "account_number": "",
              "bank_identifier": "",
              "bank_identifier_code": "",
              "iban": "GB78BARC12345678901234",
              "swift": ""
          },
          "debtor_name": "Jorge Corp",
          "debtor_account": {
              "account_name": "Cool Account",
              "account_number": "1234567890",
              "bank_identifier": "123456",
              "bank_identifier_code": "",
              "iban": "",
              "swift": "RACZHUH1123"
          }
        }
    ]
}
```

This model is a representation of the webhook for a credit transaction.

**Fields**

<ResponseField name="data" type="array">
  Always present. A list of [Transaction](/api/transaction-models#transactiondata)
</ResponseField>

### Payment Webhook Status

Status of the payment's webhook

**Values**

| Value | Description |
| - | - |
| `CREATED` | Payment has been created. |
| `PENDING_OF_AUTHORIZATION` | Payment is waiting for authorization. |
| `AUTHORIZED` | Payment has been authorized. |
| `REJECTED` | Payment has been rejected. |
| `CANCELLED` | Payment has been cancelled. |
| `SENT` | Payment instruction sent to payment scheme. |
| `PENDING_RETURN` | Payment is pending return. |
| `RETURNED` | Payment has been returned. |
| `INVALIDATED` | Payment has been invalidated. |

### OnboardingStatusChange

Will give notification about the change of status during onboarding a client. Example of onboarding message is on a side, more information about onboarding can be found on [onboarding documentation](https://docs.onboarding.ebury.io/?version=latest#f3ea9e99-4068-4860-bebc-853b596d99ff).

<Note>
  Note: Ebury Mass Payments customers will not receive notifications for the `ONBOARDING_STATUS_CHANGE` webhook type. Please take this limitation into account.
</Note>

```json theme={null}
{
  "data": [
    {
      "type": "onboardingRequest",
      "links": {
        "self": "/provision/v2/onboarding/0013N00000CAZrWQAX"
      },
      "id": "0013N00000CAZrWQAX",
      "attributes": {
        "OnboardingStatus": "Client Onboarded",
        "AccountNumber": "455053",
        "EburyId": "ECECLI455053",
        "BecameClient": "2020-04-01"
      }
    }
  ]
}
```

## Webhook Examples

Scenarios presented in this section should be considered as examples. Feel free to modify them to better fit your needs.

Most of the examples will only contain the GraphQL query. As explained earlier, this becomes the string value of the `query` field in the HTTP POST request payload .

When you create your subscription you should specify which type of notification you are interested in.
You can always change it by [patching the subscription](#patch-a-subscription).

As a reminder, the first example includes both the query and the related HTTP request.

## Create a subscription

```graphql theme={null}
mutation {
    createSubscription(input: {
        subscription: {
            active: true
            secret: "secret"
            url: "https://httpbin.org/post"
            types: [TRADE_STATUS_CHANGE]
            extraHeaders: [
                {
                    name: "x-custom-header",
                    value: "myheadervalue"
                }
            ]
        }
    }) {
        subscription {
            id
        }
    }
}
```

```http theme={null}
POST /webhooks/graphql HTTP/1.1
Authorization: Bearer $access_token
Content-Type: application/json
X-Client-ID: $client_id

{
  "query": "mutation createSubscription{\n    createSubscription(\n        input: {\n            active: true\n             secret: \"secret\"\n             url: \"https://httpbin.org/post\"\n       types: [TRADE_STATUS_CHANGE]\n       }\n    ) {\n        subscription {\n            id\n        }\n    }\n}",
  "variables": {}
}
```

```json Response theme={null}
HTTP/1.1 200 OK
Content-Type: application/json; charset=utf-8
Content-Length: 94
Connection: close
Date: Mon, 13 Apr 2020 11:19:09 GMT

{
  "data": {
    "createSubscription": {
      "subscription": {
        "id": "c7677669-8dd6-4deb-923c-c38eb6b65789"
      }
    }
  }
}
```

In order to receive notifications, the first step is to create a subscription.

Make sure to **only** include `active: true` in the payload if you want to receive notifications right after creation. Otherwise you can enable the subscription later.

Once a subscription is active, notifications related to the client will be sent to the specified URL.

Note that the `secret` is optional and will be used as a key to [sign the payload](#securing-your-webhooks).

The `extraHeaders` field is also optional and will be used to [add static headers](#custom-headers) into all the subscription requests.

Note that the `types` must be present and will specify which type of notification you want to receive.
If you are not sure which types of notification you want to receive you can specify all of them and update them later on by [patching the subscription](#patch-a-subscription).

As mentioned earlier, we will have to use a so-called `mutation`. The corresponding GraphQL function is `createSubscription`, requiring subscription URL and status as parameters.

1. GraphQL query (example snippet #1)
2. The query embedded into a HTTP request payload (example #2)
3. The HTTP response object (example #3)

## Ping a subscription

```http theme={null}
POST /webhooks/ping/c7677669-8dd6-4deb-923c-c38eb6b65789 HTTP/1.1
Authorization: Bearer $access_token
Content-Type: application/json
X-Client-ID: $client_id
```

```http Response theme={null}
HTTP/1.1 204 No Content
```

If you need to check the connectivity of a subscription, even if it is disabled, you can send a **ping** event.
To do that, you only need to `POST`, with all the usual headers, the path `/webhooks/ping/:subscription_id:`.
This endpoint does not require a body as input and neither does it return anything: it is only a `POST` call that will generate a `204` response.
Calling the endpoint will generate a ping event to simulate the workflow of a regular webhook, triggering a notification for the configured URL.

The `Ping` webhook is a special one since it is sent to specific subscriptions.
You can expect the communication between this API and your webhook receiver to follow the same rules as other types of webhooks.
The header `X-Ebury-Client-Id` will be populated, and `X-Ebury-Webhook` will contain the special value `Ping`.
The payload will be a valid `json` without any specific schema, apart from being signed in `X-Ebury-Signature` as usual.

### Example webhook request format

When Ebury sends a webhook to your endpoint, the request will include headers similar to:

```
POST /webhook HTTP/1.1
Host: your-webhook-endpoint.com
User-Agent: python-requests/2.28.1
Accept-Encoding: gzip, deflate
Accept: */*
Connection: keep-alive
Content-Type: application/json
X-Ebury-Client-Id: EBPCLI00004
X-Ebury-Webhook: Ping
X-Ebury-Signature: sha3-256=56f34d8aaeddd5919e3153c86e7afa56d3f7e3594ab213c4a23d074fd8cd9985
X-Ebury-Notification-Id: a06f7a12-3dc2-4de5-97f6-17850e669378
X-Ebury-Delivery-Id: 720db90f-8146-40a4-8d52-c2c14136f225
X-Ebury-Attempt-Number: 1
Content-Length: 99
```

## Get the list of subscriptions

```graphql theme={null}
{
    subscriptions {
        totalCount
        nodes {
            id
            createdAt
            url
            active
            types
        }
    }
}
```

```graphql theme={null}
{
    subscriptions(filter: {
        active: {
            equalTo: true
        }
    }) {
        totalCount
        nodes {
            id
            createdAt
            url
            active
            types
        }
    }
}
```

Two example usages, to

* query the list of all subscriptions (example #1),
* or filter only for the active ones (example #2),

## Delete a subscription

```graphql theme={null}
mutation deleteSubscription($id: UUID!){
    deleteSubscription(
        input: {
            id: $id
        }
    ) {
        subscription {
            id
        }
    }
}
```

```json theme={null}
{
    "id": "c9f8f293-3391-4cc7-9a97-cb0e26d901e9"
}
```

```http theme={null}
POST /webhooks/graphql HTTP/1.1
Authorization: Bearer $access_token
Content-Type: application/json
X-Client-ID: $client_id

{
  "query": "mutation deleteSubscription($id: UUID!){\n    deleteSubscription(\n        input: {\n            id: $id\n        }\n    ) {\n        subscription {\n            id\n        }\n    }\n}",
  "variables": {
    "id": "c9f8f293-3391-4cc7-9a97-cb0e26d901e9"
  }
}
```

To delete a subscription you will need to send a `mutation` object, invoking the `deleteSubscription` GraphQL function.

In this example, we create a query with an input variable, and then we send the value of the variable.

To make it easier to follow, we include

1. GraphQL query and internal variable definition (example #1a + #1b)
2. HTTP request with all embedded in the payload (example #2)

## Enable a subscription

```graphql theme={null}
mutation enableSubscription($id: UUID!){
    updateSubscription(
        input: {
            id: $id
            patch: {
                active: true
            }
        }
    ) {
        subscription {
            id
            active
        }
    }
}
```

```json theme={null}
{
    "id": "c9f8f293-3391-4cc7-9a97-cb0e26d901e9"
}
```

If you want to change the status (`active` property) of a subscription, you need to apply a `mutation` invoking the `updateSubscription` GraphQL function.

## Disable a subscription

```graphql theme={null}
mutation disableSubscription($id: UUID!){
    updateSubscription(
        input: {
            id: $id
            patch: {
                active: false
            }
        }
    ) {
        subscription {
            id
            active
        }
    }
}
```

```json theme={null}
{
    "id": "c9f8f293-3391-4cc7-9a97-cb0e26d901e9"
}
```

Disabling a subscription goes just the same.

## Get the last notification of every subscription

```graphql theme={null}
{
    subscriptions {
        nodes {
            active
            createdAt
            id
            url
            types
            notifications(first:1, orderBy:CREATED_AT_DESC) {
                totalCount
                nodes {
                    id
                    createdAt
                    body
                    attempts {
                        totalCount
                    }
                }
            }
        }
    }
}
```

The power of GraphQL relies on the ability to navigate across data relationships.

This will allow us to efficiently retrieve a list of subscriptions, with the latest notification belonging to each.

Note that we are using a combination of two options to get the latest notification.

* `orderBy` attribute making sure that the first notification attempt is the newest
* `first: 1`: to get no more but the first (*one*) notification attempt

## Patch a subscription

Patching a subscription is a useful way to change the scope of your notification by changing the types
of event you are interested in. When you are not sure which types of events are important for you, you can subscribe
for all and then unsubscribe undesired events by patching your subscription.
When changing the types, you need to specify the whole new list of types.

Few examples of patching your type values:

* `types: []` subscribe to none types of events, will have similar effect like disable the subscription by setting Active to False.

* `types: [TRADE_STATUS_CHANGE, PAYMENT_STATUS_CHANGE, CREDIT_INCOMING_TRANSACTION, CREDIT_MARGIN_TRANSACTION, CREDIT_PAYMENT_RETURNED_TRANSACTION, ONBOARDING_STATUS_CHANGE, CREDIT_TRANSACTION, DEBIT_TRANSACTION]` subscribe to all types of events

* `types: [TRADE_STATUS_CHANGE, CREDIT_INCOMING_TRANSACTION]]` subscription to only 2 events type

```graphql theme={null}
mutation updateSubscription($id: UUID!, $url: String!, $types: [WebhookType!]){
    updateSubscription(
        input: {
            id: $id
            patch: {
                url: $url
                types: $types
            }
        }
    ) {
        subscription {
            id
            url
            active
            types
        }
    }
}
```

```json theme={null}
{
    "id": "ad1e5009-2a8e-44c9-922f-b7da22f66325",
    "url": "https://example.com/",
    "types": ["TRADE_STATUS_CHANGE", "CREDIT_INCOMING_TRANSACTION"]
}
```

If you want to change the url and event types of a subscription, you need to update it as such:

## Responses

```http Response theme={null}
HTTP/1.1 200 OK
Content-Type: application/json; charset=utf-8
Content-Length: 94
Connection: close
Date: Mon, 13 Apr 2020 11:19:09 GMT

{
  "data": {
    "createSubscription": {
      "subscription": {
        "id": "c7677669-8dd6-4deb-923c-c38eb6b65789"
      }
    }
  }
}
```

### Success

A successful request will return a `200 OK` response with a map.

This map will include an entry with

* a `data` field
  * that will further include the requested operation
    * that will further include fields that were requested for the response.

### Failure

See [Error Reporting](#error-reporting) for details of unsuccessful requests.
