Overview

Webhook

Webhook Overview

Creating a Webhook

Listing Webhooks

Deleting a Webhook

Event

Event Overview

Handling Webhook Events

Getting an Event

Listing Events

Updating an Event

Best Practices

Best Practices

Verify Digital Signatures

Allowlist Stark Bank Static IPs

Return 200 Quickly

Handle Duplicates and Out-of-Order Events

Handle Unfamiliar Event Types Gracefully

React to the Right Event

Exempt Your Webhook Route from CSRF Protection

Test in Sandbox First

Build Resilience with Event Polling

Webhook

Webhooks allow you to receive real-time notifications whenever events occur in your workspace, such as payments received, transfers completed, or boletos paid.

Instead of polling the API for updates, you register a URL and Stark Bank will send a POST request to it every time a relevant event happens.

Every webhook event is signed with a digital signature that our SDKs verify automatically, ensuring the authenticity of each notification.

Below you will learn how to subscribe to events, handle them securely, and build a resilient integration.

NOTE: Read Core Concepts before continuing this guide.

RESOURCE SUMMARY
Subscribe to events by registering your endpoint URL.
Process and verify the events delivered to your endpoint.
Security, resilience, and reliability recommendations.

Webhook Overview

A Webhook subscription tells Stark Bank where to send event notifications. You provide an HTTPS URL and a list of event types you want to receive.

Your endpoint must use a valid TLS/SSL certificate — self-signed certificates are not supported.

Available subscriptions: deposit, invoice, brcode-payment, transfer, utility-payment, boleto, boleto-payment, darf-payment, payment-request, boleto-holmes.

Subscribe only to the event types your application needs. This reduces unnecessary traffic and simplifies your event handler.

Creating a Webhook

Register a new webhook by providing your endpoint URL and the event types you want to subscribe to.

You can subscribe to one or more event types at once. Each webhook will only receive events for the subscriptions you specify.

Python

import starkbank

webhook = starkbank.webhook.create(
    url="https://winterfell.westeros.gov/events-from-stark-bank",
    subscriptions=[
        "boleto",
        "boleto-payment",
        "transfer",
        "utility-payment"
    ]
)

print(webhook)
  

Javascript

const starkbank = require('starkbank');

(async() => {
    let webhook = await starkbank.webhook.create({
        url: 'https://winterfell.westeros.gov/events-from-stark-bank',
        subscriptions: ['transfer', 'boleto', 'boleto-payment', 'utility-payment'],
    });

    console.log(webhook);
})();
  

PHP

$webhook = StarkBank\Webhook::create([
    "url" => "https://winterfell.westeros.gov/events-from-stark-bank",
    "subscriptions" => ["boleto", "boleto-payment", "transfer", "utility-payment"]
]);

print_r($webhook);
  

Java

import com.starkbank.*;
import java.util.HashMap;

HashMap<String, Object> data = new HashMap<>();
data.put("url", "https://winterfell.westeros.gov/events-from-stark-bank");
data.put("subscriptions", new String[]{"boleto", "boleto-payment", "transfer", "utility-payment"});
Webhook webhook = Webhook.create(data);

System.out.println(webhook);
  

Ruby

require('starkbank')

webhook = StarkBank::Webhook.create(
    url: 'https://winterfell.westeros.gov/events-from-stark-bank',
    subscriptions: %w[boleto boleto-payment transfer utility-payment]
)

puts webhook
  

Elixir

webhook = StarkBank.Webhook.create!(
    url: "https://winterfell.westeros.gov/events-from-stark-bank",
    subscriptions: [
        "boleto",
        "boleto-payment",
        "transfer",
        "utility-payment"
    ]
)

webhook |> IO.inspect
  

C#

using System;

StarkBank.Webhook webhook = StarkBank.Webhook.Create(
    url: "https://winterfell.westeros.gov/events-from-stark-bank",
    subscriptions: new List<string> { "transfer", "boleto", "boleto-payment", "utility-payment" }
);
  

Go

package main

import (
    "fmt"
    "github.com/starkbank/sdk-go/starkbank/webhook"
)

func main() {

    webhook, err := webhook.Create(
        webhook.Webhook{
            Url:           "https://winterfell.westeros.gov/events-from-stark-bank",
            Subscriptions: []string{"boleto", "boleto-payment", "transfer", "utility-payment"},
        }, nil)
    if err.Errors != nil {
        for _, e := range err.Errors {
            fmt.Printf("code: %s, message: %s", e.Code, e.Message)
        }
    }
    fmt.Printf("%+v", webhook)
}
  

Clojure

(def webhook
  (starkbank.webhook/create
    {
      :url "https://winterfell.westeros.gov/events-from-stark-bank"
      :subscriptions ["transfer" "boleto" "boleto-payment" "utility-payment"]
    }))
(dorun (map println webhook))
  

Curl

curl --location --request POST '{{baseUrl}}/v2/webhook' 
--header 'Access-Id: {{accessId}}' 
--header 'Access-Time: {{accessTime}}' 
--header 'Access-Signature: {{accessSignature}}' 
--header 'Content-Type: application/json' 
--data-raw '{
    "url": "https://winterfell.westeros.gov/events-from-stark-bank",
    "subscriptions": ["boleto", "boleto-payment", "transfer", "utility-payment"]
}'
  
RESPONSE

Python

Webhook(
    id=6225875037061120,
    subscriptions=['boleto', 'boleto-payment', 'transfer', 'utility-payment'],
    url=https://winterfell.westeros.gov/events-from-stark-bank
)
  

Javascript

Webhook {
    id: '6225875037061120',
    url: 'https://winterfell.westeros.gov/events-from-stark-bank',
    subscriptions: [ 'transfer', 'boleto', 'boleto-payment', 'utility-payment' ]
}
  

PHP

StarkBank\Webhook Object
(
    [id] => 6225875037061120
    [url] => https://winterfell.westeros.gov/events-from-stark-bank
    [subscriptions] => Array
        (
            [0] => boleto
            [1] => boleto-payment
            [2] => transfer
            [3] => utility-payment
        )

)
  

Java

Webhook({
  "id": "6225875037061120",
  "url": "https://winterfell.westeros.gov/events-from-stark-bank",
  "subscriptions": ["boleto", "boleto-payment", "transfer", "utility-payment"]
})
  

Ruby

webhook(
  id: 6225875037061120,
  url: https://winterfell.westeros.gov/events-from-stark-bank,
  subscriptions: ["boleto", "boleto-payment", "transfer", "utility-payment"]
)
  

Elixir

%StarkBank.Webhook{
    id: "6225875037061120",
    url: "https://winterfell.westeros.gov/events-from-stark-bank",
    subscriptions: [
        "boleto",
        "boleto-payment",
        "transfer",
        "utility-payment"
    ]
}
  

C#

Webhook(
    Url: https://winterfell.westeros.gov/events-from-stark-bank,
    Subscriptions: { transfer, boleto, boleto-payment, utility-payment },
    ID: 6225875037061120
)
  

Go

{
    Url:https://winterfell.westeros.gov/events-from-stark-bank
    Subscriptions:[boleto boleto-payment transfer utility-payment]
    Id:6225875037061120
}
  

Clojure

{:id "6225875037061120",
 :url "https://winterfell.westeros.gov/events-from-stark-bank",
 :subscriptions
 ["boleto" "boleto-payment" "transfer" "utility-payment"]}
  

Curl

{
    "message": "Webhook successfully created",
    "webhook": {
        "id": "6225875037061120",
        "url": "https://winterfell.westeros.gov/events-from-stark-bank",
        "subscriptions": [
            "boleto",
            "boleto-payment",
            "transfer",
            "utility-payment"
        ]
    }
}
  

Listing Webhooks

You can list all active webhook subscriptions to check your current configuration.

Python

import starkbank

webhooks = starkbank.webhook.query()

for webhook in webhooks:
    print(webhook)
  

Javascript

const starkbank = require('starkbank');

(async() => {
    let webhooks = await starkbank.webhook.query();

    for await (let webhook of webhooks) {
        console.log(webhook);
    }
})();
  

PHP

$webhooks = StarkBank\Webhook::query();

foreach($webhooks as $webhook){
    print_r($webhook);
}
  

Java

import com.starkbank.*;
import com.starkbank.utils.Generator;

Generator<Webhook> webhooks = Webhook.query();

for (Webhook webhook : webhooks){
    System.out.println(webhook);
}
  

Ruby

require('starkbank')

webhooks = StarkBank::Webhook.query()

webhooks.each do |webhook|
    puts webhook
end
  

Elixir

webhooks = StarkBank.Webhook.query!()

for webhook <- webhooks do
    webhook |> IO.inspect
end
  

C#

using System;
using System.Collections.Generic;

IEnumerable<StarkBank.Webhook> webhooks = StarkBank.Webhook.Query();

foreach(StarkBank.Webhook webhook in webhooks)
{
    Console.WriteLine(webhook);
}
  

Go

package main

import (
    "fmt"
    "github.com/starkbank/sdk-go/starkbank/webhook"
)

func main() {

    webhooks, errorChannel := webhook.Query(nil, nil)

    loop:
    for {
        select {
        case err := <-errorChannel:
            if err.Errors != nil {
                for _, e := range err.Errors {
                    fmt.Printf("code: %s, message: %s", e.Code, e.Message)
                }
            }
        case webhook, ok := <-webhooks:
            if !ok {
                break loop
            }
            fmt.Printf("%+v", webhook)
        }
    }
}
  

Clojure

(def webhooks (starkbank.webhook/query))
(dorun (map println webhooks))
  

Curl

curl --location --request GET '{{baseUrl}}/v2/webhook' 
--header 'Access-Id: {{accessId}}' 
--header 'Access-Time: {{accessTime}}' 
--header 'Access-Signature: {{accessSignature}}'
  
RESPONSE

Python

Webhook(
    id=6225875037061120,
    subscriptions=['boleto', 'boleto-payment', 'transfer', 'utility-payment'],
    url=https://winterfell.westeros.gov/events-from-stark-bank
)
  

Javascript

Webhook {
    url: 'https://winterfell.westeros.gov/events-from-stark-bank',
    subscriptions: [ 'transfer', 'boleto', 'boleto-payment', 'utility-payment' ],
    id: '6225875037061120'
}
  

PHP

StarkBank\Webhook Object
(
    [id] => 6225875037061120
    [url] => https://winterfell.westeros.gov/events-from-stark-bank
    [subscriptions] => Array
        (
            [0] => boleto
            [1] => boleto-payment
            [2] => transfer
            [3] => utility-payment
        )

)
  

Java

Webhook({
    "id": "6225875037061120",
    "url": "https://winterfell.westeros.gov/events-from-stark-bank",
    "subscriptions": ["boleto", "boleto-payment", "transfer", "utility-payment"]
})
  

Ruby

webhook(
    id: 6225875037061120,
    url: https://winterfell.westeros.gov/events-from-stark-bank,
    subscriptions: ["boleto", "boleto-payment", "transfer", "utility-payment"]
)
  

Elixir

%StarkBank.Webhook{
    id: "4844331563220992",
    url: "https://winterfell.westeros.gov/events-from-stark-bank",
    subscriptions: [
        "boleto",
        "boleto-payment",
        "transfer",
        "utility-payment"
    ]
}
  

C#

Webhook(
    Url: https://webhook.site/60e9c18e-4b5c-4369-bda1-ab5fcd8e1b29,
    Subscriptions: { transfer, boleto, boleto-payment, utility-payment },
    ID: 6225875037061120
)
  

Go

{
    Url:https://winterfell.westeros.gov/events-from-stark-bank
    Subscriptions:[boleto boleto-payment transfer utility-payment]
    Id:6225875037061120
}
  

Clojure

{:id "6225875037061120",
 :url "https://winterfell.westeros.gov/events-from-stark-bank",
 :subscriptions
 ["boleto" "boleto-payment" "transfer" "utility-payment"]}
  

Curl

{
    "cursor": null,
    "webhooks": [
        {
            "id": "6225875037061120",
            "url": "https://winterfell.westeros.gov/events-from-stark-bank",
            "subscriptions": [
                "boleto",
                "boleto-payment",
                "transfer",
                "utility-payment"
            ]
        }
    ]
}
  

Deleting a Webhook

Delete a webhook subscription when you no longer want to receive events at that URL.

This action cannot be undone.

Python

import starkbank

webhook = starkbank.webhook.delete("6225875037061120")

print(webhook)
  

Javascript

const starkbank = require('starkbank');

(async() => {
    let webhook = await starkbank.webhook.delete('6225875037061120');
    console.log(webhook);
})();
  

PHP

$webhook = StarkBank\Webhook::delete("6225875037061120");

print_r($webhook);
  

Java

import com.starkbank.*;

Webhook webhook = Webhook.delete("6225875037061120");

System.out.println(webhook);
  

Ruby

require('starkbank')

webhook = StarkBank::Webhook.delete('6225875037061120')

puts webhook
  

Elixir

webhook = StarkBank.Webhook.delete!("6225875037061120")

webhook |> IO.inspect
  

C#

using System;

StarkBank.Webhook webhook = StarkBank.Webhook.Delete("6225875037061120");

Console.WriteLine(webhook);
  

Go

package main

import (
    "fmt"
    "github.com/starkbank/sdk-go/starkbank/webhook"
)

func main() {

    webhook, err := webhook.Delete("6225875037061120", nil)
    if err.Errors != nil {
        for _, e := range err.Errors {
            fmt.Printf("code: %s, message: %s", e.Code, e.Message)
        }
    }

    fmt.Printf("%+v", webhook)
}
  

Clojure

(def webhook (starkbank.webhook/delete "6225875037061120"))
(println webhook)
  

Curl

curl --location --request DELETE '{{baseUrl}}/v2/webhook/6225875037061120' 
--header 'Access-Id: {{accessId}}' 
--header 'Access-Time: {{accessTime}}' 
--header 'Access-Signature: {{accessSignature}}'
  
RESPONSE

Python

Webhook(
    id=6225875037061120,
    subscriptions=['boleto', 'boleto-payment', 'transfer', 'utility-payment'],
    url=https://winterfell.westeros.gov/events-from-stark-bank
)
  

Javascript

Webhook {
    id: '6225875037061120',
    url: 'https://winterfell.westeros.gov/events-from-stark-bank',
    subscriptions: [ 'boleto', 'boleto-payment', 'transfer', 'utility-payment' ]
}
  

PHP

StarkBank\Webhook Object
(
    [id] => 6225875037061120
    [url] => https://winterfell.westeros.gov/events-from-stark-bank
    [subscriptions] => Array
        (
            [0] => boleto
            [1] => boleto-payment
            [2] => transfer
            [3] => utility-payment
        )

)
  

Java

Webhook({
    "id": "6225875037061120",
    "url": "https://winterfell.westeros.gov/events-from-stark-bank",
    "subscriptions": ["boleto", "boleto-payment", "transfer", "utility-payment"]
})
  

Ruby

webhook(
  id: 6225875037061120,
  url: https://winterfell.westeros.gov/events-from-stark-bank,
  subscriptions: ["boleto", "boleto-payment", "transfer", "utility-payment"]
)
  

Elixir

%StarkBank.Webhook{
    id: "6225875037061120",
    url: "https://winterfell.westeros.gov/events-from-stark-bank",
    subscriptions: [
        "boleto",
        "boleto-payment",
        "transfer",
        "utility-payment"
    ]
}
  

C#

Webhook(
    Url: https://webhook.site/60e9c18e-4b5c-4369-bda1-ab5fcd8e1b29,
    Subscriptions: { transfer, boleto, boleto-payment, utility-payment },
    ID: 6225875037061120
)
  

Go

{
    Url:https://winterfell.westeros.gov/events-from-stark-bank
    Subscriptions:[boleto boleto-payment transfer utility-payment]
    Id:6225875037061120
}
  

Clojure

{:id "6225875037061120",
 :url "https://winterfell.westeros.gov/events-from-stark-bank",
 :subscriptions
 ["boleto" "boleto-payment" "transfer" "utility-payment"]}
  

Curl

{
    "message": "Webhook successfully deleted",
    "webhook": {
        "id": "6225875037061120",
        "url": "https://winterfell.westeros.gov/events-from-stark-bank",
        "subscriptions": [
            "boleto",
            "boleto-payment",
            "transfer",
            "utility-payment"
        ]
    }
}
  

Event Overview

Every time a log is created for a subscribed resource, Stark Bank generates an Event and delivers it to your webhook URL via a POST request.

Each event contains a subscription field indicating the resource type (e.g. transfer, invoice) and a log property with the details of what changed. The nature of the log depends on the subscription that triggered the event.

Handling Webhook Events

When Stark Bank sends an event to your webhook URL, it includes a Digital-Signature header. Use the SDK's event.parse() method to both parse the event and verify the signature automatically.

The SDK verifies the signature using Stark Bank's public key, ensuring the event was genuinely sent by Stark Bank. Never process events without verifying the signature.

Python

import starkbank


request = listen()  # this is the method you made to get the events posted to your Webhook endpoint

event = starkbank.event.parse(
    content=request.data.decode("utf-8"),
    signature=request.headers["Digital-Signature"],
)

if "transfer" in event.subscription:
    print(event.log.request)
    

Javascript

const starkbank = require('starkbank');
const express = require('express')
const app = express()

app.use(express.raw({type: "*/*"}));

const port = 3000
app.get('/', async (req, res) => {
    try {
        let event = await starkbank.event.parse({
            content: req.body.toString(),
            signature: req.headers['Digital-Signature']
        });
        if (event.subscription === 'transfer') {
            console.log(event.log.request);
        }
        res.end()
    }
    catch (err) {
        console.log(err)
        res.status(400).end()
    }
})
app.listen(port, () => console.log('Example app listening at http://localhost:{port}'))
    

PHP

use StarkBank\Event;


$response = listen()  # this is the method you made to get the events posted to your Webhook

$event = Event::parse(
    $response->content,
    $response->headers["Digital-Signature"]
);

if ($event->subscription == "transfer"){
    print_r($event->log->request);
    

Java

import com.starkbank.*;


Request request = Listener.listen(); // this is the method you made to get the events posted to your Webhook

String content = request.content.toString();
String signature = request.headers.get("Digital-Signature");

Event event = Event.parse(content, signature);
if(event.subscription == "transfer"){) {
    Transfer.Log log = ((Event.Transfer) event).log;
    System.out.println(log.request);
}
    

Ruby

require('starkbank')


request = listen()  # this is the method you made to get the events posted to your Webhook

event = StarkBank::Event.parse(
    content: request.body.read,
    signature: request.headers['Digital-Signature']
)

if event.subscription == 'transfer'
    puts event.log.request
end
    

Elixir

response = listen()  # this is the function you made to get the events posted to your Webhook

{event, cache_pid} = StarkBank.Event.parse!(
    content: response.content,
    signature: response.headers["Digital-Signature"]
) |> IO.inspect
    

C#

using System;


Response response = listen();  // this is the method you made to get the events posted to your Webhook endpoint

StarkBank.Event parsedEvent = StarkBank.Event.Parse(
    content: response.Content,
    signature: response.Headers["Digital-Signature"]
);

if (parsedEvent.Subscription == "transfer") {
    StarkBank.Transfer.Log log = transfer.Log as StarkBank.Transfer.Log;
    Console.WriteLine(log.request);
}
    

Go

Not yet available. Please contact us if you need this SDK.

Clojure

Not yet available. Please contact us if you need this SDK.

Curl

Not yet available. Please contact us if you need this SDK.
RESPONSE

Python

{
  "event": {
    "created": "2024-02-01T02:06:27.872660+00:00",
    "id": "5258020443389952",
    "log": {
      "created": "2024-02-01T02:06:26.317809+00:00",
      "errors": [],
      "id": "4638457385189376",
      "transfer": {
        "accountNumber": "123456-0",
        "accountType": "checking",
        "amount": 10000,
        "bankCode": "001",
        "branchCode": "1234",
        "created": "2024-02-01T02:06:26.294998+00:00",
        "description": "Payment for service #1234",
        "externalId": "my_external_id",
        "fee": 0,
        "id": "6679150966341632",
        "metadata": {},
        "name": "Steve Rogers",
        "rules": [
          {
            "key": "resendingLimit",
            "value": 5
          }
        ],
        "scheduled": "2024-12-02T10:00:00+00:00",
        "status": "success",
        "tags": [
          "debts",
          "food"
        ],
        "taxId": "330.731.970-10",
        "transactionIds": [],
        "updated": "2024-02-01T02:06:26.317865+00:00"
      },
      "type": "success"
    },
    "subscription": "transfer",
    "workspaceId": "6341320293482496"
  }
}
    

Javascript

{
  "event": {
    "created": "2024-02-01T02:06:27.872660+00:00",
    "id": "5258020443389952",
    "log": {
      "created": "2024-02-01T02:06:26.317809+00:00",
      "errors": [],
      "id": "4638457385189376",
      "transfer": {
        "accountNumber": "123456-0",
        "accountType": "checking",
        "amount": 10000,
        "bankCode": "001",
        "branchCode": "1234",
        "created": "2024-02-01T02:06:26.294998+00:00",
        "description": "Payment for service #1234",
        "externalId": "my_external_id",
        "fee": 0,
        "id": "6679150966341632",
        "metadata": {},
        "name": "Steve Rogers",
        "rules": [
          {
            "key": "resendingLimit",
            "value": 5
          }
        ],
        "scheduled": "2024-12-02T10:00:00+00:00",
        "status": "success",
        "tags": [
          "debts",
          "food"
        ],
        "taxId": "330.731.970-10",
        "transactionIds": [],
        "updated": "2024-02-01T02:06:26.317865+00:00"
      },
      "type": "success"
    },
    "subscription": "transfer",
    "workspaceId": "6341320293482496"
  }
}
    

PHP

{
  "event": {
    "created": "2024-02-01T02:06:27.872660+00:00",
    "id": "5258020443389952",
    "log": {
      "created": "2024-02-01T02:06:26.317809+00:00",
      "errors": [],
      "id": "4638457385189376",
      "transfer": {
        "accountNumber": "123456-0",
        "accountType": "checking",
        "amount": 10000,
        "bankCode": "001",
        "branchCode": "1234",
        "created": "2024-02-01T02:06:26.294998+00:00",
        "description": "Payment for service #1234",
        "externalId": "my_external_id",
        "fee": 0,
        "id": "6679150966341632",
        "metadata": {},
        "name": "Steve Rogers",
        "rules": [
          {
            "key": "resendingLimit",
            "value": 5
          }
        ],
        "scheduled": "2024-12-02T10:00:00+00:00",
        "status": "success",
        "tags": [
          "debts",
          "food"
        ],
        "taxId": "330.731.970-10",
        "transactionIds": [],
        "updated": "2024-02-01T02:06:26.317865+00:00"
      },
      "type": "success"
    },
    "subscription": "transfer",
    "workspaceId": "6341320293482496"
  }
}
    

Java

{
  "event": {
    "created": "2024-02-01T02:06:27.872660+00:00",
    "id": "5258020443389952",
    "log": {
      "created": "2024-02-01T02:06:26.317809+00:00",
      "errors": [],
      "id": "4638457385189376",
      "transfer": {
        "accountNumber": "123456-0",
        "accountType": "checking",
        "amount": 10000,
        "bankCode": "001",
        "branchCode": "1234",
        "created": "2024-02-01T02:06:26.294998+00:00",
        "description": "Payment for service #1234",
        "externalId": "my_external_id",
        "fee": 0,
        "id": "6679150966341632",
        "metadata": {},
        "name": "Steve Rogers",
        "rules": [
          {
            "key": "resendingLimit",
            "value": 5
          }
        ],
        "scheduled": "2024-12-02T10:00:00+00:00",
        "status": "success",
        "tags": [
          "debts",
          "food"
        ],
        "taxId": "330.731.970-10",
        "transactionIds": [],
        "updated": "2024-02-01T02:06:26.317865+00:00"
      },
      "type": "success"
    },
    "subscription": "transfer",
    "workspaceId": "6341320293482496"
  }
}
    

Ruby

{
  "event": {
    "created": "2024-02-01T02:06:27.872660+00:00",
    "id": "5258020443389952",
    "log": {
      "created": "2024-02-01T02:06:26.317809+00:00",
      "errors": [],
      "id": "4638457385189376",
      "transfer": {
        "accountNumber": "123456-0",
        "accountType": "checking",
        "amount": 10000,
        "bankCode": "001",
        "branchCode": "1234",
        "created": "2024-02-01T02:06:26.294998+00:00",
        "description": "Payment for service #1234",
        "externalId": "my_external_id",
        "fee": 0,
        "id": "6679150966341632",
        "metadata": {},
        "name": "Steve Rogers",
        "rules": [
          {
            "key": "resendingLimit",
            "value": 5
          }
        ],
        "scheduled": "2024-12-02T10:00:00+00:00",
        "status": "success",
        "tags": [
          "debts",
          "food"
        ],
        "taxId": "330.731.970-10",
        "transactionIds": [],
        "updated": "2024-02-01T02:06:26.317865+00:00"
      },
      "type": "success"
    },
    "subscription": "transfer",
    "workspaceId": "6341320293482496"
  }
}
    

Elixir

{
  "event": {
    "created": "2024-02-01T02:06:27.872660+00:00",
    "id": "5258020443389952",
    "log": {
      "created": "2024-02-01T02:06:26.317809+00:00",
      "errors": [],
      "id": "4638457385189376",
      "transfer": {
        "accountNumber": "123456-0",
        "accountType": "checking",
        "amount": 10000,
        "bankCode": "001",
        "branchCode": "1234",
        "created": "2024-02-01T02:06:26.294998+00:00",
        "description": "Payment for service #1234",
        "externalId": "my_external_id",
        "fee": 0,
        "id": "6679150966341632",
        "metadata": {},
        "name": "Steve Rogers",
        "rules": [
          {
            "key": "resendingLimit",
            "value": 5
          }
        ],
        "scheduled": "2024-12-02T10:00:00+00:00",
        "status": "success",
        "tags": [
          "debts",
          "food"
        ],
        "taxId": "330.731.970-10",
        "transactionIds": [],
        "updated": "2024-02-01T02:06:26.317865+00:00"
      },
      "type": "success"
    },
    "subscription": "transfer",
    "workspaceId": "6341320293482496"
  }
}
    

C#

{
  "event": {
    "created": "2024-02-01T02:06:27.872660+00:00",
    "id": "5258020443389952",
    "log": {
      "created": "2024-02-01T02:06:26.317809+00:00",
      "errors": [],
      "id": "4638457385189376",
      "transfer": {
        "accountNumber": "123456-0",
        "accountType": "checking",
        "amount": 10000,
        "bankCode": "001",
        "branchCode": "1234",
        "created": "2024-02-01T02:06:26.294998+00:00",
        "description": "Payment for service #1234",
        "externalId": "my_external_id",
        "fee": 0,
        "id": "6679150966341632",
        "metadata": {},
        "name": "Steve Rogers",
        "rules": [
          {
            "key": "resendingLimit",
            "value": 5
          }
        ],
        "scheduled": "2024-12-02T10:00:00+00:00",
        "status": "success",
        "tags": [
          "debts",
          "food"
        ],
        "taxId": "330.731.970-10",
        "transactionIds": [],
        "updated": "2024-02-01T02:06:26.317865+00:00"
      },
      "type": "success"
    },
    "subscription": "transfer",
    "workspaceId": "6341320293482496"
  }
}
    

Go

{
  "event": {
    "created": "2024-02-01T02:06:27.872660+00:00",
    "id": "5258020443389952",
    "log": {
      "created": "2024-02-01T02:06:26.317809+00:00",
      "errors": [],
      "id": "4638457385189376",
      "transfer": {
        "accountNumber": "123456-0",
        "accountType": "checking",
        "amount": 10000,
        "bankCode": "001",
        "branchCode": "1234",
        "created": "2024-02-01T02:06:26.294998+00:00",
        "description": "Payment for service #1234",
        "externalId": "my_external_id",
        "fee": 0,
        "id": "6679150966341632",
        "metadata": {},
        "name": "Steve Rogers",
        "rules": [
          {
            "key": "resendingLimit",
            "value": 5
          }
        ],
        "scheduled": "2024-12-02T10:00:00+00:00",
        "status": "success",
        "tags": [
          "debts",
          "food"
        ],
        "taxId": "330.731.970-10",
        "transactionIds": [],
        "updated": "2024-02-01T02:06:26.317865+00:00"
      },
      "type": "success"
    },
    "subscription": "transfer",
    "workspaceId": "6341320293482496"
  }
}
    

Clojure

{
  "event": {
    "created": "2024-02-01T02:06:27.872660+00:00",
    "id": "5258020443389952",
    "log": {
      "created": "2024-02-01T02:06:26.317809+00:00",
      "errors": [],
      "id": "4638457385189376",
      "transfer": {
        "accountNumber": "123456-0",
        "accountType": "checking",
        "amount": 10000,
        "bankCode": "001",
        "branchCode": "1234",
        "created": "2024-02-01T02:06:26.294998+00:00",
        "description": "Payment for service #1234",
        "externalId": "my_external_id",
        "fee": 0,
        "id": "6679150966341632",
        "metadata": {},
        "name": "Steve Rogers",
        "rules": [
          {
            "key": "resendingLimit",
            "value": 5
          }
        ],
        "scheduled": "2024-12-02T10:00:00+00:00",
        "status": "success",
        "tags": [
          "debts",
          "food"
        ],
        "taxId": "330.731.970-10",
        "transactionIds": [],
        "updated": "2024-02-01T02:06:26.317865+00:00"
      },
      "type": "success"
    },
    "subscription": "transfer",
    "workspaceId": "6341320293482496"
  }
}
    

Curl

{
  "event": {
    "created": "2024-02-01T02:06:27.872660+00:00",
    "id": "5258020443389952",
    "log": {
      "created": "2024-02-01T02:06:26.317809+00:00",
      "errors": [],
      "id": "4638457385189376",
      "transfer": {
        "accountNumber": "123456-0",
        "accountType": "checking",
        "amount": 10000,
        "bankCode": "001",
        "branchCode": "1234",
        "created": "2024-02-01T02:06:26.294998+00:00",
        "description": "Payment for service #1234",
        "externalId": "my_external_id",
        "fee": 0,
        "id": "6679150966341632",
        "metadata": {},
        "name": "Steve Rogers",
        "rules": [
          {
            "key": "resendingLimit",
            "value": 5
          }
        ],
        "scheduled": "2024-12-02T10:00:00+00:00",
        "status": "success",
        "tags": [
          "debts",
          "food"
        ],
        "taxId": "330.731.970-10",
        "transactionIds": [],
        "updated": "2024-02-01T02:06:26.317865+00:00"
      },
      "type": "success"
    },
    "subscription": "transfer",
    "workspaceId": "6341320293482496"
  }
}
    

Getting an Event

You can get a specific event by its ID to inspect its details.

Python

import starkbank

event = starkbank.event.get("4537025176797184")

print(event)
  

Javascript

const starkbank = require('starkbank');

(async() => {
    let event = await starkbank.event.get('4537025176797184');
    console.log(event);
})();
  

PHP

$event = StarkBank\Event::get("4537025176797184");

print_r($event);
  

Java

import com.starkbank.*;

Event event = Event.get("4537025176797184");

System.out.println(event);
  

Ruby

require('starkbank')

event = StarkBank::Event.get('4537025176797184')

puts event
  

Elixir

event = StarkBank.Event.get!("4537025176797184")

event |> IO.inspect
  

C#

using System;

StarkBank.Event eventObject = StarkBank.Event.Get("4537025176797184");

Console.WriteLine(eventObject);
  

Go

package main

import (
    "fmt"
    "github.com/starkbank/sdk-go/starkbank/event"
)

func main() {

    event, err := event.Get("4537025176797184", nil)
    if err.Errors != nil {
        for _, e := range err.Errors {
            fmt.Printf("code: %s, message: %s", e.Code, e.Message)
        }
    }

    fmt.Printf("%+v", event)
}
  

Clojure

(def event (starkbank.event/get "4537025176797184"))
(println event)
  

Curl

curl --location --request GET '{{baseUrl}}/v2/event/4537025176797184' 
--header 'Access-Id: {{accessId}}' 
--header 'Access-Time: {{accessTime}}' 
--header 'Access-Signature: {{accessSignature}}'
  
RESPONSE

Python

Event(
    id=4537025176797184,
    is_delivered=False,
    subscription=transfer,
    created=2020-04-24 17:49:10.181589,
    log=Log(
        id=5662318377566208,
        created=2020-04-24 17:49:09.348444,
        errors=[],
        type=sending,
        transfer=Transfer(
            id=5950134772826112,
            account_number=76543-8,
            amount=100000000,
            bank_code=665,
            branch_code=2201,
            created=2020-04-24 17:49:08.748893,
            fee=200,
            name=Daenerys Targaryen Stormborn,
            status=processing,
            tags=['daenerys', 'invoice/1234'],
            tax_id=594.739.480-42,
            transaction_ids=['5991715760504832'],
            updated=2020-04-24 17:49:09.632271
        )
    ),
    workspace_id=1231231231231231
)
  

Javascript

Event {
    id: '4537025176797184',
    created: '2020-04-24T17:49:10.847726+00:00',
    isDelivered: false,
    subscription: 'transfer',
    log: {
        id: '5662318377566208',
        errors: [],
        type: 'sending',
        created: '2020-04-24T17:49:09.884128+00:00',
        payment: {
            id: '5950134772826112'
            accountNumber: '76543-8',
            amount: 10785,
            bankCode: '665',
            branchCode: '2201',
            created: '2020-04-24T17:49:08.038706+00:00',
            fee: 200,
            name: 'Daenerys Targaryen Stormborn',
            status: 'processing',
            tags: ['daenerys', 'invoice/1234'],
            taxId: '594.739.480-42',
            transactionIds: ['5991715760504832'],
            updated: '2020-04-24T17:49:09.038706+00:00',
        }
    },
    workspaceId='1231231231231231'
}
  

PHP

StarkBank\Event Object
(
    [id] => 4537025176797184
    [isDelivered] => false
    [subscription] => transfer
    [created] => DateTime Object
        (
            [date] => 2020-04-24 17:49:10.616917
            [timezone_type] => 1
            [timezone] => +00:00
        )

    [log] => StarkBank\Transfer\Log Object
        (
            [id] => 5662318377566208
            [created] => DateTime Object
                (
                    [date] => 2020-04-24 17:49:09.844960
                    [timezone_type] => 1
                    [timezone] => +00:00
                )

            [type] => sending
            [errors] => Array
                (
                )

            [transfer] => StarkBankTransfer Object
                (
                    [id] => 5950134772826112
                    [amount] => 100000000
                    [name] => Daenerys Targaryen Stormborn
                    [taxId] => 594.739.480-42
                    [bankCode] => 665
                    [branchCode] => 2201
                    [accountNumber] => 76543-8
                    [tags] => Array
                        (
                            [0] => daenerys
                            [1] => invoice/1234
                        )

                    [fee] => 200
                    [status] => processing
                    [transactionIds] => Array
                        (
                            [0] => 5991715760504832
                        )

                    [created] => DateTime Object
                        (
                            [date] => 2020-04-24 17:49:08.277606
                            [timezone_type] => 1
                            [timezone] => +00:00
                        )

                    [updated] => DateTime Object
                        (
                            [date] => 2020-04-24 17:49:09.090932
                            [timezone_type] => 1
                            [timezone] => +00:00
                        )

                )

        )

    [workspaceId] => 1231231231231231

)
  

Java

Event({
    "id": "4537025176797184",
    "created": "2020-04-24T17:49:10+00:00",
    "isDelivered": false,
    "subscription": "transfer",
    "log": {
        "id": "5662318377566208",
        "created": "2020-04-24T17:49:13+00:00",
        "type": "registered",
        "errors": [],
        "transfer": {
            "id": "5429309233692672",
            "accountNumber": "76543-8",
            "amount": 100000000,
            "bankCode": "665",
            "branchCode": "2201",
            "created": "2020-04-24T17:49:13+00:00"
            "fee": 200,
            "name": "Daenerys Targaryen Stormborn",
            "status": "processing",
            "tags": ["daenerys", "invoice/1234"],
            "taxId": "594.739.480-42",
            "transactionIds": ["5991715760504832"],
            "updated": "2020-04-24T17:49:13+00:00"
        }
    },
    "workspaceId": 1231231231231231
})
  

Ruby

event(
    id: 4537025176797184,
    created: 2020-04-24T17:49:10+00:00,
    is_delivered: false,
    subscription: transfer,
    log: log(
        id: 5662318377566208,
        created: 2020-04-24T17:49:09+00:00,
        type: sending,
        errors: [],
        transfer: transfer(
            id: 5950134772826112,
            account_number: 76543-8,
            amount: 100000000,
            bank_code: 665,
            branch_code: 2201,
            created: 2020-04-24T17:49:09+00:00
            fee: 200,
            name: Daenerys Targaryen Stormborn,
            status: processing,
            tags: ["daenerys", "invoice/1234"],
            tax_id: 594.739.480-42,
            transaction_ids: ["5991715760504832"],
            updated: 2020-04-24T17:49:09+00:00
        )
    ),
    workspace_id: 1231231231231231
)
  

Elixir

%StarkBank.Event{
    id: "4537025176797184",
    is_delivered: false,
    subscription: "transfer",
    created: ~U[2020-04-24 17:49:09.594656Z],
    log: %StarkBank.Transfer.Log{
        id: "5662318377566208",
        created: ~U[2020-04-24 17:49:09.049096Z],
        errors: [],
        type: "sending",
        payment: %StarkBank.Transfer{
            id: "5950134772826112",
            account_number: 76543-8,
            amount: 11631,
            bank_code: "665",
            branch_code: "2201",
            created: ~U[2020-04-24 17:49:09.713657Z],
            fee: 200,
            name: "Daenerys Targaryen Stormborn",
            status: "processing",
            tags: ["daenerys", "invoice/1234"],
            tax_id: "594.739.480-42"
            transaction_ids: ["5991715760504832"],
            updated: ~U[2020-04-24 17:49:09.713657Z]
        }
    },
    workspace_id: "1231231231231231"
}
  

C#

Event(
    ID: 4537025176797184,
    IsDelivered: False,
    Subscription: transfer,
    Created: 04/24/2020 17:49:09,
    Log: Log(
        ID: 5662318377566208,
        Created: 04/24/2020 17:49:09,
        Type: sending,
        Errors: {  },
        Transfer: Transfer(
            ID: 5950134772826112
            AccountNumber: 76543-8,
            Amount: 100000000,
            BankCode: 665,
            BranchCode: 2201,
            Created: 04/24/2020 17:49:09,
            Fee: 200,
            Name: Daenerys Targaryen Stormborn,
            Status: processing,
            Tags: { daenerys, invoice/1234 },
            TaxID: 594.739.480-42,
            TransactionIds: { 5991715760504832 },
            Updated: 04/24/2020 17:49:09
        )
    ),
    WorkspaceId: 1231231231231231
)
  

Go

{
    Id:4537025176797184
    Log:{
        Id:5662318377566208
        Transfer:{
            Id:5950134772826112
            AccountNumber:76543-8
            Amount:1000000
            BankCode:665
            BranchCode:2201
            Created:2020-04-24 17:49:10.38386 +0000 +0000
            Fine:200
            Name:Daenerys Targaryen Stormborn
            Status:processing
            Tags:[daenerys invoice/1234]
            TaxId:594.739.480-42
            TransactionIds:[5991715760504832]
            Created:2020-04-24 17:49:09.38386 +0000 +0000
        }
        Errors:[]
        Type:sending
        Created:2020-04-24 17:49:09.126413 +0000 +0000
    }
    Created:2020-04-24 17:49:09.464471 +0000 +0000
    IsDelivered:false
    Subscription:transfer
    WorkspaceId:1231231231231231
}
  

Clojure

{:id "4537025176797184",
 :created "2020-04-24T17:49:09.359338+00:00",
 :is-delivered false,
 :subscription "transfer",
 :log
 {:id "5662318377566208",
  :created "2020-04-24T17:49:09.703951+00:00",
  :errors [],
  :type "sending",
  :transfer
  {:id "5950134772826112",
   :account-number 76543-8,
   :amount 100000000,
   :bank-code "665",
   :branch-code "2201",
   :created "2020-04-24T17:49:09.128124+00:00",
   :fee 200,
   :name "Daenerys Targaryen Stormborn",
   :status "processing",
   :tags ["daenerys" "invoice/1234"],
   :transaction-ids ["5991715760504832"],
   :updated "2020-04-24T17:49:09.128124+00:00"}}
 :workspace-id "1231231231231231"}
  

Curl

{
    "message": "Event successfully deleted",
    "event": {
        "id": "4537025176797184",
        "isDelivered": false,
        "subscription": "transfer",
        "created": "2020-04-24T17:49:00.201602+00:00",
        "log": {
            "id": "5662318377566208",
            "errors": [],
            "type": "sending",
            "created": "2020-04-24T17:49:09.751122+00:00",
            "transfer": {
                "id": "5950134772826112",
                "accountNumber": "76543-8",
                "amount": 100000000,
                "bankCode": "665",
                "branchCode": "2201",
                "created": "2020-04-24T17:49:09.130246+00:00",
                "fee": 200,
                "name": "Daenerys Targaryen Stormborn",
                "status": "processing",
                "taxId": "594.739.480-42",
                "tags": ["daenerys", "invoice/1234"],
                "transactionIds": ["5991715760504832"],
                "updated": "2020-04-24T17:49:02.130255+00:00",
            }
        },
        "workspaceId": "1231231231231231"
    }
}
  

Listing Events

You can list all events that match your filters. Use the isDelivered parameter to filter events that haven't been successfully delivered.

This is especially useful for building a resilience mechanism: periodically query for undelivered events, process them, and mark them as delivered.

Python

import starkbank

events = starkbank.event.query(
    is_delivered=False,
    after="2020-04-01",
    before="2020-04-30"
)

for event in events:
    print(event)
  

Javascript

const starkbank = require('starkbank');

(async() => {
    let events = await starkbank.event.query({
        isDelivered: false,
        after: '2020-04-01',
        before: '2020-04-30',
    });

    for await (let event of events) {
        console.log(event);
    }
})();
  

PHP

$events = StarkBank\Event::query([
    "isDelivered" => false,
    "after" => "2020-04-01",
    "before" => "2020-04-30"
]);

foreach($events as $event){
    print_r($event);
}
  

Java

import com.starkbank.*;
import com.starkbank.utils.Generator;
import java.util.HashMap;

HashMap<String, Object> params = new HashMap<>();
params.put("isDelivered", false);
params.put("after", "2020-04-01");
params.put("before", "2020-04-30");
Generator<Event> events = Event.query(params);

for (Event event : events){
    System.out.println(event);
}
  

Ruby

require('starkbank')

events = StarkBank::Event.query(
    after: '2020-04-01',
    before: '2020-04-30',
    is_delivered: false
)

events.each do |event|
    puts event
end
  

Elixir

events = StarkBank.Event.query!(
    after: "2020-04-01",
    before: "2020-04-30",
    is_delivered: false
)

for event <- events do
    event |> IO.inspect
end
  

C#

using System;
using System.Collections.Generic;

IEnumerable<StarkBank.Event> events = StarkBank.Event.Query(
    after: new DateTime(2020, 4, 1),
    before: new DateTime(2020, 4, 30),
    isDelivered: false
);

foreach(StarkBank.Event eventObject in events)
{
    Console.WriteLine(eventObject);
}
  

Go

package main

import (
    "fmt"
    "time"
    "github.com/starkbank/sdk-go/starkbank/event"
)

func main() {

    var params = map[string]interface{}{}
    params["isDelivered"] = false
    params["after"] = time.Date(2020, 4, 1, 0, 0, 0, 0, time.UTC)
    params["before"] = time.Date(2020, 4, 30, 0, 0, 0, 0, time.UTC)

    events, errorChannel := event.Query(params, nil)

    loop:
    for {
        select {
        case err := <-errorChannel:
            if err.Errors != nil {
                for _, e := range err.Errors {
                    fmt.Printf("code: %s, message: %s", e.Code, e.Message)
                }
            }
        case event, ok := <-events:
            if !ok {
                break loop
            }
            fmt.Printf("%+v", event)
        }
    }
}
  

Clojure

(def events
  (starkbank.event/query
    {
      :after "2020-03-20"
      :before "2020-04-30"
      :is-delivered false
    }))
(dorun (map println events))
  

Curl

curl --location --request GET '{{baseUrl}}/v2/event' 
--header 'Access-Id: {{accessId}}' 
--header 'Access-Time: {{accessTime}}' 
--header 'Access-Signature: {{accessSignature}}'
  
RESPONSE

Python

Event(
    id=4537025176797184,
    is_delivered=False,
    subscription=transfer,
    created=2020-04-24 17:49:10.181589,
    log=Log(
        id=5662318377566208,
        created=2020-04-24 17:49:09.348444,
        errors=[],
        type=sending,
        transfer=Transfer(
            id=5950134772826112,
            account_number=76543-8,
            amount=100000000,
            bank_code=665,
            branch_code=2201,
            created=2020-04-24 17:49:08.748893,
            fee=200,
            name=Daenerys Targaryen Stormborn,
            status=processing,
            tags=['daenerys', 'invoice/1234'],
            tax_id=594.739.480-42,
            transaction_ids=['5991715760504832'],
            updated=2020-04-24 17:49:09.632271
        )
    ),
    workspace_id=1231231231231231
)
  

Javascript

Event {
    id: '4537025176797184',
    created: '2020-04-24T17:49:10.847726+00:00',
    isDelivered: false,
    subscription: 'transfer',
    log: {
        id: '5662318377566208',
        errors: [],
        type: 'sending',
        created: '2020-04-24T17:49:09.884128+00:00',
        payment: {
            id: '5950134772826112'
            accountNumber: '76543-8',
            amount: 10785,
            bankCode: '665',
            branchCode: '2201',
            created: '2020-04-24T17:49:08.038706+00:00',
            fee: 200,
            name: 'Daenerys Targaryen Stormborn',
            status: 'processing',
            tags: ['daenerys', 'invoice/1234'],
            taxId: '594.739.480-42',
            transactionIds: ['5991715760504832'],
            updated: '2020-04-24T17:49:09.038706+00:00',
        }
    },
    workspaceId='1231231231231231'
}
  

PHP

StarkBank\Event Object
(
    [id] => 4537025176797184
    [isDelivered] => false
    [subscription] => transfer
    [created] => DateTime Object
        (
            [date] => 2020-04-24 17:49:10.616917
            [timezone_type] => 1
            [timezone] => +00:00
        )

    [log] => StarkBank\Transfer\Log Object
        (
            [id] => 5662318377566208
            [created] => DateTime Object
                (
                    [date] => 2020-04-24 17:49:09.844960
                    [timezone_type] => 1
                    [timezone] => +00:00
                )

            [type] => sending
            [errors] => Array
                (
                )

            [transfer] => StarkBank\Transfer Object
                (
                    [id] => 5950134772826112
                    [amount] => 100000000
                    [name] => Daenerys Targaryen Stormborn
                    [taxId] => 594.739.480-42
                    [bankCode] => 665
                    [branchCode] => 2201
                    [accountNumber] => 76543-8
                    [tags] => Array
                        (
                            [0] => daenerys
                            [1] => invoice/1234
                        )

                    [fee] => 200
                    [status] => processing
                    [transactionIds] => Array
                        (
                            [0] => 5991715760504832
                        )

                    [created] => DateTime Object
                        (
                            [date] => 2020-04-24 17:49:08.277606
                            [timezone_type] => 1
                            [timezone] => +00:00
                        )

                    [updated] => DateTime Object
                        (
                            [date] => 2020-04-24 17:49:09.090932
                            [timezone_type] => 1
                            [timezone] => +00:00
                        )

                )

        )

    [workspaceId] => 1231231231231231

)
  

Java

Event({
    "id": "4537025176797184",
    "created": "2020-04-24T17:49:10+00:00",
    "isDelivered": false,
    "subscription": "transfer",
    "log": {
        "id": "5662318377566208",
        "created": "2020-04-24T17:49:13+00:00",
        "type": "registered",
        "errors": [],
        "transfer": {
            "id": "5429309233692672",
            "accountNumber": "76543-8",
            "amount": 100000000,
            "bankCode": "665",
            "branchCode": "2201",
            "created": "2020-04-24T17:49:13+00:00"
            "fee": 200,
            "name": "Daenerys Targaryen Stormborn",
            "status": "processing",
            "tags": ["daenerys", "invoice/1234"],
            "taxId": "594.739.480-42",
            "transactionIds": ["5991715760504832"],
            "updated": "2020-04-24T17:49:13+00:00"
        }
    },
    "workspaceId": 1231231231231231
})
  

Ruby

event(
    id: 4537025176797184,
    created: 2020-04-24T17:49:10+00:00,
    is_delivered: false,
    subscription: transfer,
    log: log(
        id: 5662318377566208,
        created: 2020-04-24T17:49:09+00:00,
        type: sending,
        errors: [],
        transfer: transfer(
            id: 5950134772826112,
            account_number: 76543-8,
            amount: 100000000,
            bank_code: 665,
            branch_code: 2201,
            created: 2020-04-24T17:49:09+00:00
            fee: 200,
            name: Daenerys Targaryen Stormborn,
            status: processing,
            tags: ["daenerys", "invoice/1234"],
            tax_id: 594.739.480-42,
            transaction_ids: ["5991715760504832"],
            updated: 2020-04-24T17:49:09+00:00
        )
    ),
    workspace_id: 1231231231231231
)
  

Elixir

%StarkBank.Event{
    id: "4537025176797184",
    is_delivered: false,
    subscription: "transfer",
    created: ~U[2020-04-24 17:49:09.594656Z],
    log: %StarkBank.Transfer.Log{
        id: "5662318377566208",
        created: ~U[2020-04-24 17:49:09.049096Z],
        errors: [],
        type: "sending",
        payment: %StarkBank.Transfer{
            id: "5950134772826112",
            account_number: 76543-8,
            amount: 11631,
            bank_code: "665",
            branch_code: "2201",
            created: ~U[2020-04-24 17:49:09.713657Z],
            fee: 200,
            name: "Daenerys Targaryen Stormborn",
            status: "processing",
            tags: ["daenerys", "invoice/1234"],
            tax_id: "594.739.480-42"
            transaction_ids: ["5991715760504832"],
            updated: ~U[2020-04-24 17:49:09.713657Z]
        }
    },
    workspace_id: "1231231231231231"
}
  

C#

Event(
    ID: 4537025176797184,
    IsDelivered: False,
    Subscription: transfer,
    Created: 04/24/2020 17:49:09,
    Log: Log(
        ID: 5662318377566208,
        Created: 04/24/2020 17:49:09,
        Type: sending,
        Errors: {  },
        Transfer: Transfer(
            ID: 5950134772826112
            AccountNumber: 76543-8,
            Amount: 100000000,
            BankCode: 665,
            BranchCode: 2201,
            Created: 04/24/2020 17:49:09,
            Fee: 200,
            Name: Daenerys Targaryen Stormborn,
            Status: processing,
            Tags: { daenerys, invoice/1234 },
            TaxID: 594.739.480-42,
            TransactionIds: { 5991715760504832 },
            Updated: 04/24/2020 17:49:09
        )
    ),
    WorkspaceId: 1231231231231231
)
  

Go

{
    Id:4537025176797184
    Log:{
        Id:5662318377566208
        Transfer:{
            Id:5950134772826112
            AccountNumber:76543-8
            Amount:1000000
            BankCode:665
            BranchCode:2201
            Created:2020-04-24 17:49:10.38386 +0000 +0000
            Fine:200
            Name:Daenerys Targaryen Stormborn
            Status:processing
            Tags:[daenerys invoice/1234]
            TaxId:594.739.480-42
            TransactionIds:[5991715760504832]
            Created:2020-04-24 17:49:09.38386 +0000 +0000
        }
        Errors:[]
        Type:sending
        Created:2020-04-24 17:49:09.126413 +0000 +0000
    }
    Created:2020-04-24 17:49:09.464471 +0000 +0000
    IsDelivered:false
    Subscription:transfer
    WorkspaceId:1231231231231231
}
  

Clojure

{:id "4537025176797184",
 :created "2020-04-24T17:49:09.359338+00:00",
 :is-delivered false,
 :subscription "transfer",
 :log
 {:id "5662318377566208",
  :created "2020-04-24T17:49:09.703951+00:00",
  :errors [],
  :type "sending",
  :transfer
  {:id "5950134772826112",
   :account-number 76543-8,
   :amount 100000000,
   :bank-code "665",
   :branch-code "2201",
   :created "2020-04-24T17:49:09.128124+00:00",
   :fee 200,
   :name "Daenerys Targaryen Stormborn",
   :status "processing",
   :tags ["daenerys" "invoice/1234"],
   :transaction-ids ["5991715760504832"],
   :updated "2020-04-24T17:49:09.128124+00:00"}}
 :workspace-id "1231231231231231"}
  

Curl

{
    "cursor": null,
    "events": [
        {
            "id": "4537025176797184",
            "isDelivered": false,
            "subscription": "transfer",
            "created": "2020-04-24T17:49:00.201602+00:00",
            "log": {
                "id": "5662318377566208",
                "errors": [],
                "type": "sending",
                "created": "2020-04-24T17:49:09.751122+00:00",
                "transfer": {
                    "id": "5950134772826112",
                    "accountNumber": "76543-8",
                    "amount": 100000000,
                    "bankCode": "665",
                    "branchCode": "2201",
                    "created": "2020-04-24T17:49:09.130246+00:00",
                    "fee": 200,
                    "name": "Daenerys Targaryen Stormborn",
                    "status": "processing",
                    "taxId": "594.739.480-42",
                    "tags": ["daenerys", "invoice/1234"],
                    "transactionIds": ["5991715760504832"],
                    "updated": "2020-04-24T17:49:02.130255+00:00",
                }
            },
            "workspaceId": "1231231231231231"
        }
    ]
}
  

Updating an Event

After processing an event, you can mark it as delivered by updating the isDelivered property to true.

This is particularly useful after recovering from server downtime: list all undelivered events, process them, and then set them as delivered.

Python

import starkbank

event = starkbank.event.update(
    "4537025176797184",
    is_delivered=True
)

print(event)
  

Javascript

const starkbank = require('starkbank');

(async() => {
    let event = await starkbank.event.update(
        '4537025176797184',
        {isDelivered: true}
    );
    console.log(event);
})();
  

PHP

$event = StarkBank\Event::update(
    "4537025176797184",
    ["isDelivered" => true]
);

print_r($event);
  

Java

import com.starkbank.*;
import java.util.HashMap;

HashMap<String, Object> params = new HashMap<>();
params.put("isDelivered", true);
Event event = Event.update(
    "4537025176797184",
    params
);

System.out.println(event);
  

Ruby

require('starkbank')

event = StarkBank::Event.update(
    '4537025176797184',
    is_delivered: true
)

puts event
  

Elixir

event = StarkBank.Event.update!(
    "4537025176797184",
    is_delivered: true
)

event |> IO.inspect
  

C#

using System;

StarkBank.Event eventObject = StarkBank.Event.Update(
    "4537025176797184",
    isDelivered: true
);

Console.WriteLine(eventObject);
  

Go

package main

import (
    "fmt"
    "github.com/starkbank/sdk-go/starkbank/event"
)

func main() {

    patchData := map[string]interface{}{}
    patchData["isDelivered"] = true

    event, err := event.Update(
        "4537025176797184",
        patchData,
        nil,
    )
    if err.Errors != nil {
        for _, e := range err.Errors {
            fmt.Printf("code: %s, message: %s", e.Code, e.Message)
        }
    }

    fmt.Printf("%+v", event)
}
  

Clojure

(def event
  (starkbank.event/update
    "4537025176797184"
    {:is-delivered true}))
(println event)
  

Curl

curl --location --request PATCH '{{baseUrl}}/v2/event/4537025176797184' 
--header 'Access-Id: {{accessId}}' 
--header 'Access-Time: {{accessTime}}' 
--header 'Access-Signature: {{accessSignature}}' 
--header 'Content-Type: application/json' 
--data-raw '{
    "isDelivered": true
}'
  
RESPONSE

Python

Event(
    id=4537025176797184,
    is_delivered=True,
    subscription=transfer,
    created=2020-04-24 17:49:10.181589,
    log=Log(
        id=5662318377566208,
        created=2020-04-24 17:49:09.348444,
        errors=[],
        type=sending,
        transfer=Transfer(
            id=5950134772826112,
            account_number=76543-8,
            amount=100000000,
            bank_code=665,
            branch_code=2201,
            created=2020-04-24 17:49:08.748893,
            fee=200,
            name=Daenerys Targaryen Stormborn,
            status=processing,
            tags=['daenerys', 'invoice/1234'],
            tax_id=594.739.480-42,
            transaction_ids=['5991715760504832'],
            updated=2020-04-24 17:49:09.632271
        )
    ),
    workspace_id=1231231231231231
)
  

Javascript

Event {
    id: '4537025176797184',
    created: '2020-04-24T17:49:10.847726+00:00',
    isDelivered: true,
    subscription: 'transfer',
    log: {
        id: '5662318377566208',
        errors: [],
        type: 'sending',
        created: '2020-04-24T17:49:09.884128+00:00',
        payment: {
            id: '5950134772826112'
            accountNumber: '76543-8',
            amount: 10785,
            bankCode: '665',
            branchCode: '2201',
            created: '2020-04-24T17:49:08.038706+00:00',
            fee: 200,
            name: 'Daenerys Targaryen Stormborn',
            status: 'processing',
            tags: ['daenerys', 'invoice/1234'],
            taxId: '594.739.480-42',
            transactionIds: ['5991715760504832'],
            updated: '2020-04-24T17:49:09.038706+00:00',
        }
    },
    workspaceId='1231231231231231'
}
  

PHP

StarkBank\Event Object
(
    [id] => 4537025176797184
    [isDelivered] => true
    [subscription] => transfer
    [created] => DateTime Object
        (
            [date] => 2020-04-24 17:49:10.616917
            [timezone_type] => 1
            [timezone] => +00:00
        )

    [log] => StarkBankTransferLog Object
        (
            [id] => 5662318377566208
            [created] => DateTime Object
                (
                    [date] => 2020-04-24 17:49:09.844960
                    [timezone_type] => 1
                    [timezone] => +00:00
                )

            [type] => sending
            [errors] => Array
                (
                )

            [transfer] => StarkBankTransfer Object
                (
                    [id] => 5950134772826112
                    [amount] => 100000000
                    [name] => Daenerys Targaryen Stormborn
                    [taxId] => 594.739.480-42
                    [bankCode] => 665
                    [branchCode] => 2201
                    [accountNumber] => 76543-8
                    [tags] => Array
                        (
                            [0] => daenerys
                            [1] => invoice/1234
                        )

                    [fee] => 200
                    [status] => processing
                    [transactionIds] => Array
                        (
                            [0] => 5991715760504832
                        )

                    [created] => DateTime Object
                        (
                            [date] => 2020-04-24 17:49:08.277606
                            [timezone_type] => 1
                            [timezone] => +00:00
                        )

                    [updated] => DateTime Object
                        (
                            [date] => 2020-04-24 17:49:09.090932
                            [timezone_type] => 1
                            [timezone] => +00:00
                        )

                )

        )

    [workspaceId] => 1231231231231231
)
  

Java

Event({
    "id": "4537025176797184",
    "created": "2020-04-24T17:49:10+00:00",
    "isDelivered": true,
    "subscription": "transfer",
    "log": {
        "id": "5662318377566208",
        "created": "2020-04-24T17:49:13+00:00",
        "type": "registered",
        "errors": [],
        "transfer": {
            "id": "5429309233692672",
            "accountNumber": "76543-8",
            "amount": 100000000,
            "bankCode": "665",
            "branchCode": "2201",
            "created": "2020-04-24T17:49:13+00:00"
            "fee": 200,
            "name": "Daenerys Targaryen Stormborn",
            "status": "processing",
            "tags": ["daenerys", "invoice/1234"],
            "taxId": "594.739.480-42",
            "transactionIds": ["5991715760504832"],
            "updated": "2020-04-24T17:49:13+00:00"
        }
    },
    "workspaceId": 1231231231231231
})
  

Ruby

event(
    id: 4537025176797184,
    created: 2020-04-24T17:49:10+00:00,
    is_delivered: true,
    subscription: transfer,
    log: log(
        id: 5662318377566208,
        created: 2020-04-24T17:49:09+00:00,
        type: sending,
        errors: [],
        transfer: transfer(
            id: 5950134772826112,
            account_number: 76543-8,
            amount: 100000000,
            bank_code: 665,
            branch_code: 2201,
            created: 2020-04-24T17:49:09+00:00
            fee: 200,
            name: Daenerys Targaryen Stormborn,
            status: processing,
            tags: ["daenerys", "invoice/1234"],
            tax_id: 594.739.480-42,
            transaction_ids: ["5991715760504832"],
            updated: 2020-04-24T17:49:09+00:00
        )
    ),
    workspace_id: 1231231231231231
)
  

Elixir

%StarkBank.Event{
    id: "4537025176797184",
    is_delivered: true,
    subscription: "transfer",
    created: ~U[2020-04-24 17:49:09.594656Z],
    log: %StarkBank.Transfer.Log{
        id: "5662318377566208",
        created: ~U[2020-04-24 17:49:09.049096Z],
        errors: [],
        type: "sending",
        payment: %StarkBank.Transfer{
            id: "5950134772826112",
            account_number: 76543-8,
            amount: 11631,
            bank_code: "665",
            branch_code: "2201",
            created: ~U[2020-04-24 17:49:09.713657Z],
            fee: 200,
            name: "Daenerys Targaryen Stormborn",
            status: "processing",
            tags: ["daenerys", "invoice/1234"],
            tax_id: "594.739.480-42"
            transaction_ids: ["5991715760504832"],
            updated: ~U[2020-04-24 17:49:09.713657Z]
        }
    },
    workspace_id: "1231231231231231"
}
  

C#

Event(
    ID: 4537025176797184,
    IsDelivered: true,
    Subscription: transfer,
    Created: 04/24/2020 17:49:09,
    Log: Log(
        ID: 5662318377566208,
        Created: 04/24/2020 17:49:09,
        Type: sending,
        Errors: {  },
        Transfer: Transfer(
            ID: 5950134772826112
            AccountNumber: 76543-8,
            Amount: 100000000,
            BankCode: 665,
            BranchCode: 2201,
            Created: 04/24/2020 17:49:09,
            Fee: 200,
            Name: Daenerys Targaryen Stormborn,
            Status: processing,
            Tags: { daenerys, invoice/1234 },
            TaxID: 594.739.480-42,
            TransactionIds: { 5991715760504832 },
            Updated: 04/24/2020 17:49:09
        )
    ),
    WorkspaceId: 1231231231231231
)
  

Go

{
    Id:4537025176797184
    Log:{
        Id:5662318377566208
        Transfer:{
            Id:5950134772826112
            AccountNumber:76543-8
            Amount:1000000
            BankCode:665
            BranchCode:2201
            Created:2020-04-24 17:49:10.38386 +0000 +0000
            Fine:200
            Name:Daenerys Targaryen Stormborn
            Status:processing
            Tags:[daenerys invoice/1234]
            TaxId:594.739.480-42
            TransactionIds:[5991715760504832]
            Created:2020-04-24 17:49:09.38386 +0000 +0000
        }
        Errors:[]
        Type:sending
        Created:2020-04-24 17:49:09.126413 +0000 +0000
    }
    Created:2020-04-24 17:49:09.464471 +0000 +0000
    IsDelivered:true
    Subscription:transfer
    WorkspaceId:1231231231231231
}
  

Clojure

{:id "4537025176797184",
 :created "2020-04-24T17:49:09.359338+00:00",
 :is-delivered true,
 :subscription "transfer",
 :log
 {:id "5662318377566208",
  :created "2020-04-24T17:49:09.703951+00:00",
  :errors [],
  :type "sending",
  :transfer
  {:id "5950134772826112",
   :account-number 76543-8,
   :amount 100000000,
   :bank-code "665",
   :branch-code "2201",
   :created "2020-04-24T17:49:09.128124+00:00",
   :fee 200,
   :name "Daenerys Targaryen Stormborn",
   :status "processing",
   :tags ["daenerys" "invoice/1234"],
   :transaction-ids ["5991715760504832"],
   :updated "2020-04-24T17:49:09.128124+00:00"}}
 :workspace-id "1231231231231231"}
  

Curl

{
    "message": "Event successfully patched",
    "event": {
        "id": "4537025176797184",
        "isDelivered": true,
        "subscription": "transfer",
        "created": "2020-04-24T17:49:00.201602+00:00",
        "log": {
            "id": "5662318377566208",
            "errors": [],
            "type": "sending",
            "created": "2020-04-24T17:49:09.751122+00:00",
            "transfer": {
                "id": "5950134772826112",
                "accountNumber": "76543-8",
                "amount": 100000000,
                "bankCode": "665",
                "branchCode": "2201",
                "created": "2020-04-24T17:49:09.130246+00:00",
                "fee": 200,
                "name": "Daenerys Targaryen Stormborn",
                "status": "processing",
                "taxId": "594.739.480-42",
                "tags": ["daenerys", "invoice/1234"],
                "transactionIds": ["5991715760504832"],
                "updated": "2020-04-24T17:49:02.130255+00:00",
            }
        },
        "workspaceId": "1231231231231231
    }
}

Best Practices

Follow these recommendations to build a secure and resilient webhook integration.

Verify Digital Signatures

Every event delivered to your webhook URL includes a header:

Digital-Signature

This signature is generated using Stark Bank's private key and can be verified using the public key available at:

GET /v2/public-key

Our SDKs handle this verification automatically when you use:

event.parse()

Never process events without verifying the signature first — this ensures the event was genuinely sent by Stark Bank and has not been tampered with.

Allowlist Stark Bank Static IPs

Stark Bank sends webhook events from fixed IP addresses. Add them to your firewall ingress rules to block requests from unknown sources:

Production: 35.199.76.124, 34.85.188.162

Sandbox: 35.247.226.240, 35.245.182.229

Combining IP allowlisting with digital signature verification provides defense in depth for your webhook endpoint.

Return 200 Quickly

Your webhook handler should only do three things synchronously: validate the Digital Signature, save the event to your database, and return HTTP 200. Never process the event before returning 200.

All event processing — such as updating records, triggering payments, or sending notifications — must be done asynchronously in a segregated background task. Use a message queue or job scheduler to decouple receiving from processing.

If your endpoint does not return a 200 status, Stark Bank will retry the delivery according to the following schedule:

AttemptDelay
1st retry5 minutes
2nd retry30 minutes
3rd retry120 minutes

After 3 failed attempts, the delivery will stop. Use Event Polling to recover any missed events.

Handle Duplicates and Out-of-Order Events

Events may be delivered more than once and are not guaranteed to arrive in order. Your handler must be idempotent — processing the same event twice should not cause incorrect behavior.

Guard against duplicates by logging processed event IDs and checking before processing. Do not rely on the order of event delivery — always check the current state of the resource rather than assuming a sequence.

This is especially critical for financial operations where duplicate processing could result in incorrect balances or duplicate payments.

Handle Unfamiliar Event Types Gracefully

Stark Bank may add new event types to webhooks at any time. Adding new events is not a breaking change.

Your webhook listener should gracefully handle unfamiliar event types — for example, by logging them and returning 200 — rather than failing or returning an error. This ensures your integration remains stable as the platform evolves.

React to the Right Event

More important than the order events arrive is observing the correct event to trigger your actions. Each resource goes through a lifecycle, and different events represent different stages.

For example, if you need an Invoice to be paid to complete a sale, wait for the paid event. But if you need the Invoice amount to be credited in your account before making a Transfer, wait for the credited event instead.

Reacting to the wrong event can lead to race conditions — such as trying to transfer funds that haven't been credited yet. Always match your business logic to the specific event that guarantees the precondition you need.

Exempt Your Webhook Route from CSRF Protection

If your web framework enforces CSRF token validation (e.g. Django, Rails, Laravel), your webhook endpoint will reject Stark Bank's POST requests because they don't include a CSRF token.

Exempt your webhook route from CSRF protection. The Digital Signature verification already guarantees the request authenticity.

Test in Sandbox First

Stark Bank provides a full Sandbox environment that simulates the complete event lifecycle — creation, status changes, and webhook delivery — without real money.

Register your webhook URL in Sandbox, trigger operations (e.g. create an Invoice or Transfer), and verify that your endpoint receives and processes events correctly before going live.

Sandbox and Production use separate workspaces with different API keys. Webhooks registered in one environment will not receive events from the other.

Build Resilience with Event Polling

Even with webhooks, we strongly recommend creating a daily task to:

1. Query all undelivered events using:

GET /v2/event?isDelivered=false

2. Process all undelivered events

3. Mark them as delivered using:

PATCH /v2/event/:id

isDelivered=true

This adds redundancy and resilience to your system, preventing you from having outdated information in case your system is temporarily unable to receive webhook events.