pieowlDocs
Rust

Rust

Send events to Pieowl from Rust with the HTTP API. Track events, identify users and record revenue with reqwest and serde_json.

Pieowl doesn't ship a Rust crate. You send events from Rust with a plain HTTP request to the Track API. Rust has no HTTP client in its standard library, so the example below uses the common reqwest and serde_json crates.

Before you start

You need a client ID and a client secret. Find them in the dashboard under Settings → Developers → Keys. Server requests must include the secret, so keep it on your server and load it from an environment variable.

Add the crates to your Cargo.toml:

Cargo.toml
[dependencies]
reqwest = { version = "0.12", features = ["json"] }
serde_json = "1"
tokio = { version = "1", features = ["full"] }

Send an event

Every request is a POST to https://api.pieowl.com/track with a JSON body of { "type": ..., "payload": ... }.

src/pieowl.rs
use serde_json::{json, Value};
use std::time::Duration;

const TRACK_URL: &str = "https://api.pieowl.com/track";

pub async fn send(
    client: &reqwest::Client,
    event_type: &str,
    payload: Value,
) -> Result<reqwest::StatusCode, reqwest::Error> {
    let response = client
        .post(TRACK_URL)
        .timeout(Duration::from_secs(5))
        .header("pieowl-client-id", std::env::var("PIEOWL_CLIENT_ID").unwrap_or_default())
        .header("pieowl-client-secret", std::env::var("PIEOWL_CLIENT_SECRET").unwrap_or_default())
        // Optional: forward the visitor's IP for location data
        // .header("pieowl-client-ip", visitor_ip)
        .json(&json!({ "type": event_type, "payload": payload }))
        .send()
        .await?;
    Ok(response.status())
}

Create one reqwest::Client and reuse it for every call.

Usage

Tracking events

rust
let client = reqwest::Client::new();

send(&client, "track", json!({
    "name": "signup",
    "profileId": "user_123", // optional
    "properties": { "plan": "pro" }
})).await?;

Identifying users

rust
send(&client, "identify", json!({
    "profileId": "user_123", // required
    "firstName": "Joe",
    "lastName": "Doe",
    "email": "joe@doe.com",
    "properties": { "tier": "premium" }
})).await?;

Incrementing and decrementing properties

value is optional and defaults to 1.

rust
send(&client, "increment", json!({ "profileId": "user_123", "property": "visits", "value": 1 })).await?;
send(&client, "decrement", json!({ "profileId": "user_123", "property": "credits", "value": 1 })).await?;

Tracking revenue

A purchase is a revenue event with these properties:

  • __amount: in normal units, like 49.99, not cents.
  • __currency: an ISO 4217 code, like EUR. Optional, your site currency by default.
  • __orderId: your order number. The same order sent twice counts once.
  • __deviceId: the visitor's device ID, from pieowl.getDeviceId() in the browser. The purchase is credited to their visit.

For a refund, send the same event with __refund set to true. Leave out __amount to refund the whole order. See Revenue attribution.

rust
send(&client, "track", json!({
    "name": "revenue",
    "properties": {
        "__amount": 49.99,
        "__currency": "EUR",
        "__orderId": "A-1001",
        "__deviceId": device_id
    }
})).await?;

// Refund the whole order
send(&client, "track", json!({
    "name": "revenue",
    "properties": { "__orderId": "A-1001", "__refund": true }
})).await?;

Good to know

  • Errors: send returns the HTTP status. A 2xx status means Pieowl accepted the request. Network errors come back as reqwest::Error.
  • Don't block requests: In a web server, send events with tokio::spawn so a slow call never holds up the response.
  • More event types: Groups and the full request schema are in the Track API reference.