Examples

Practical examples showing common operations with the Felloh Python SDK. Each example assumes you have already created a client instance.

Client Setup

from felloh import FellohClient
from felloh.types import FellohConfig

client = FellohClient(FellohConfig(
    public_key="your-public-key",
    private_key="your-private-key",
))

Bookings

Create a booking, then list and retrieve bookings. Amounts should be in the lowest currency denomination (e.g. pence for GBP).

Create a Booking

created = await client.bookings.create({
    "organisation": "org-id",
    "booking_reference": "REF-001",
    "customer_name": "James Dean",
    "email": "james@example.com",
    "currency": "GBX",
    "gross_amount": 100000,
    "departure_date": "2025-08-01",
    "return_date": "2025-08-15",
})

print("Booking ID:", created["data"]["id"])

List & Search Bookings

bookings = await client.bookings.list({
    "organisation": "org-id",
    "keyword": "james@example.com",
    "take": 20,
})

print(f"Found {bookings['meta']['count']} bookings")

Update a Booking

await client.bookings.update("booking-id", {
    "customer_name": "Jane Dean",
    "departure_date": "2025-09-01",
})

Delete a Booking

await client.bookings.delete("booking-id")

Booking Components

Add and remove components (e.g. flights, hotels) on a booking.

Add a Component

component = await client.booking_components.create(
    "booking-id",
    {
        "supplier": "supplier-id",
        "amount": 50000,
        "currency": "GBX",
        "booking_reference": "REF-001",
        "destination_air": "AMS",
        "type": "flights",
    },
)

Remove a Component

await client.booking_components.delete("booking-id", "component-id")

Transactions

List transactions, issue refunds, and manage pre-authorisations.

List Transactions

transactions = await client.transactions.list({
    "organisation": "org-id",
    "statuses": ["COMPLETE"],
    "date_from": "2025-01-01",
    "date_to": "2025-12-31",
})

Refund a Transaction

# Amount in lowest denomination (e.g. pence)
await client.transactions.refund("transaction-id", {
    "amount": 5000,
    "description": "Customer requested refund",
})

Complete Pre-Auth

# Capture held funds on a pre-authorised transaction
await client.transactions.complete("transaction-id")

Reverse Pre-Auth

# Release held funds on a pre-authorised transaction
await client.transactions.reverse("transaction-id")

Re-assign to Different Booking

await client.transactions.reassign("transaction-id", {
    "booking_id": "new-booking-id",
})

Create payment links to send to customers for card or open banking payments.

Create a Payment Link

link = await client.payment_links.create({
    "customer_name": "John Doe",
    "email": "john@example.com",
    "organisation": "org-id",
    "amount": 50000,
    "type": "CARD",
    "booking_id": "booking-id",
    "open_banking_enabled": True,
    "card_enabled": True,
    "description": "Holiday deposit",
    "currency": "GBX",
})

Assign a Payment Link to a Booking

await client.payment_links.assign("payment-link-id", {
    "organisation": "org-id",
    "customer_name": "John Doe",
    "email": "john@example.com",
    "booking_reference": "REF-002",
})

Ecommerce Sessions

Create ecommerce sessions for use with the browser-side JavaScript SDK.

Create an Ecommerce Session

session = await client.ecommerce.create({
    "customer_name": "Jane Smith",
    "email": "jane@example.com",
    "organisation": "org-id",
    "amount": 75000,
    "booking_id": "booking-id",
    "open_banking_enabled": True,
    "card_enabled": True,
})

# Pass session ID to the browser SDK
print("Ecommerce ID:", session["data"]["id"])

Customers

Create and list customer records.

Create a Customer

customer = await client.customers.create({
    "organisation": "org-id",
    "customer_name": "Jane Smith",
    "email": "jane@example.com",
    "address_1": "123 High Street",
    "city": "London",
    "county": "Greater London",
    "post_code": "SW1A 1AA",
})

Search Customers

customers = await client.customers.list({
    "organisation": "org-id",
    "keyword": "jane@example.com",
})

Refunds

List pending refunds and authorise or decline them.

List and Authorise Refunds

refunds = await client.refunds.list({
    "organisation": "org-id",
})

# Authorise a pending refund
await client.refunds.authorise("authorisation-code")

# Or decline it
await client.refunds.decline("authorisation-code")

Scheduled Payments

Manage stored-card (MOTO) payments and generate customer approval links.

Fetch Available Tokens

# Get stored card tokens for a booking
tokens = await client.scheduled_payments.available_tokens(
    "booking-id"
)

print(tokens["data"])
# [{"id": ..., "cardholder_name": ..., "bin": ..., "card_brand": ...}]

Create a Scheduled Payment

payment = await client.scheduled_payments.create_payment(
    "booking-id",
    {
        "token": "token-id",
        "amount": 25000,
        "date": "2025-09-01",  # optional: schedule for future
    },
)

Generate an Approval Link

approval = await client.scheduled_payments.approval_link(
    "booking-id",
    {
        "amount": 25000,
        "token": "token-id",
    },
)

print("Send to customer:", approval["data"]["url"])

Organisations & API Keys

List accessible organisations and manage API keys programmatically.

Organisations

orgs = await client.organisations.list()

for org in orgs["data"]:
    print(org["id"], org["name"])

API Keys

# Create a new API key pair
key = await client.api_keys.create({
    "organisation": "org-id",
    "name": "Production Server",
})

# Store these securely — secret_key is only returned once
print("Public:", key["data"]["public_key"])
print("Secret:", key["data"]["secret_key"])

# Delete a key
await client.api_keys.delete("key-id")

Logging

Pass a logger callback to observe every HTTP request made by the SDK.

Each LogEntry includes:

  • Name
    method
    Type
    str
    Description

    HTTP method (GET, POST, PUT, DELETE).

  • Name
    url
    Type
    str
    Description

    Full request URL including query string.

  • Name
    status_code
    Type
    int | None
    Description

    HTTP status code, or None if the request failed before receiving a response.

  • Name
    duration_ms
    Type
    float
    Description

    Request duration in milliseconds.

  • Name
    attempt
    Type
    int
    Description

    Retry attempt number (0 for the first attempt).

Request Logging

import logging

logger = logging.getLogger("felloh")

client = FellohClient(FellohConfig(
    public_key="your-public-key",
    private_key="your-private-key",
    logger=lambda entry: logger.info(
        "%s %s → %s (%dms)",
        entry.method,
        entry.url,
        entry.status_code,
        entry.duration_ms,
    ),
))