Placeholders in outbound calls - Terminal 3 Documentation

Documentation Index

Fetch the complete documentation index at: /llms.txt

Use this file to discover all available pages before exploring further.

When your contract needs to send private data (e.g., PII — name, date of birth, email, etc.) to a third-party API, it does not read the values and inline them. Instead it uses the http-with-placeholders host interface: you put {{profile.<field>}} markers in the request, and the host resolves them from the calling user’s profile inside the enclave, just before the request goes out. The plaintext never enters your WASM.

  Agent  →  z:<tid>:contract              →  host (http-with-placeholders)  →  Duffel
   book-offer      templates {{profile.*}}        resolves the markers from        POST /orders
                   into the order body            the calling user's profile,      (real PII)
                                                  then sends the rendered request
   { id, pnr } ◀───────────────────────────────────────────────────────────────  { id, pnr }

Your contract in Rust:

use crate::bindings::t3n::host::http_with_placeholders as hwp;

// The {{profile.<path>}} markers are resolved host-side from the calling
// user's profile — this contract never sees the plaintext values.
let body = serde_json::json!({
    "data": {
        "type": "instant",
        "selected_offers": [req.offer_id],
        "passengers": [{\
            "id": "passenger_0",\
            "given_name":  "{{profile.first_name}}",\
            "family_name": "{{profile.last_name}}",\
            "born_on":     "{{profile.date_of_birth}}",\
            "email":       "{{profile.verified_contacts.email.value}}",\
        }]
    }
});

let resp = hwp::call(&hwp::Request {
    method:  "POST".to_string(),
    url:     "https://api.duffel.com/air/orders".to_string(),
    headers: vec![\
        ("Authorization".to_string(), format!("Bearer {api_key}")),\
        ("Duffel-Version".to_string(), "v2".to_string()),\
        ("Content-Type".to_string(), "application/json".to_string()),\
    ],
    body: Some(serde_json::to_vec(&body)?),
})?;
// resp.body — Duffel's response (booking id + PNR). The passport/name/DOB
// were substituted by the host; your WASM never held them.

Key points: