Developers
Rust

Leal Rust SDK

Async client built on tokio, with typed request structs. Enrol customers, add stamps, redeem rewards and read a card's Apple Wallet and Google Wallet links, without writing a single HTTP request.

Package
leal
Registry
crates.io
Requires
Rust 2021 edition, with a tokio runtime.
Licence
MIT

Install

cargo add leal

Your first call

Create a token at app.getleal.com/api_tokens, keep it in an environment variable, and hand it to the client once. Every request after that carries it for you.

use leal::prelude::*;

let config = ClientConfig {
    token: Some(std::env::var("LEAL_API_TOKEN")?),
    ..Default::default()
};
let leal = LealClient::new(config)?;

let stores = leal.stores.list(None).await?;

A token reaches every store its owner belongs to. There is no separate sandbox yet, so build against a store you do not mind changing.

Common tasks

Enrol a customer

Create the customer and put them straight onto a card. The response carries the Apple Wallet and Google Wallet links, so you can send them yourself.

let customer = leal
    .customers
    .create(
        store_id,
        &CreateCustomersRequest {
            customer: CreateCustomersRequestCustomer {
                first_name: "Ada".to_string(),
                email: Some("ada@example.com".to_string()),
                ..Default::default()
            },
            card_id: Some(card_id),
            ..Default::default()
        },
        None,
    )
    .await?;

Add a stamp

The call most integrations need. Leal records the stamp, updates the wallet pass and sends the notification.

let card = leal
    .customer_cards
    .stamp(
        store_id,
        customer_id,
        customer_card_id,
        &StampCustomerCardsRequest {
            stamps: 1,
            skip_notifications: None,
        },
        None,
    )
    .await?;

Redeem a reward

Spend the stamps a customer has earned. Leal checks the reward is available before recording the redemption.

leal.customer_cards
    .redeem(
        store_id,
        customer_id,
        customer_card_id,
        &RedeemCustomerCardsRequest { reward_id },
        None,
    )
    .await?;

Handle a failure

Failures come back as an ApiError you can match on, so a rate limit is a distinct arm rather than a string to parse.

match leal.customer_cards.stamp(store_id, customer_id, customer_card_id, &request, None).await {
    Ok(card) => println!("{} stamps to the next reward", card.stamps_remaining),
    Err(ApiError::HTTP { status: 429, .. }) => {
        // Wait for the seconds in the Retry-After header, then try again.
    }
    Err(error) => return Err(error.into()),
}

Every endpoint is available, not just these. The Rust repository lists them all, and the API reference documents each field.

Rate limits and retries

Leal allows 300 requests per minute per API token. The client retries a failed request on its own, backing off between attempts, so a brief wobble does not need handling in your code. Go past the limit and you get a 429 carrying Retry-After in seconds. If you need a higher limit, ask us.

Other languages

The same API, the same methods, in eight other languages.