# Lana Feed — AI Reference > Bulk product-catalog import for merchants of the Lana network. > This file is written for AI systems: it describes what the service does, > how the import works, and which machine-readable endpoints exist. ## Site Overview Lana Feed lets a merchant take the product export their supplier or shop system already produces — a CSV, XLSX, JSON or XML file, in whatever structure it happens to have — and publish every product as a signed offer on the Lana network, where it appears in the merchant's storefront on shop.lanapays.us. It exists because a merchant with 1,000+ articles cannot reasonably enter them one at a time in a web form, and because every supplier exports a different shape of file. - URL: https://feed.lanapays.us - Machine-readable service descriptor: https://feed.lanapays.us/api/public/info - Machine-readable mapping DSL + field catalog: https://feed.lanapays.us/api/public/mapping-schema - Relay list (live): https://feed.lanapays.us/api/system-params - Image server: https://blossom.lanapays.us - Merchant storefronts: https://shop.lanapays.us - Nostr kind documentation for the whole ecosystem: https://lananostr.site ## How an import works 1. **Sign in with a merchant key.** The merchant pastes their WIF key. It is converted to a Nostr identity inside the browser and verified against their KIND 0 profile on the relays. The private key never leaves the browser: it signs both the API requests (NIP-98, kind 27235) and every offer event. 2. **Pick a business unit.** Offers belong to a KIND 30901 business unit. The unit's `category` determines which listing kind the offers are published as (see "Event kinds" below). 3. **Upload the export.** Up to 50 MB / 10,000 rows. Format is detected from content, not just the extension. Text encodings other than UTF-8 (windows-1250 and friends, common in Central European ERP exports) are detected and decoded, and the parsed sample is shown before anything else happens so mangled characters are caught immediately. Nested JSON and XML are flattened to dot-path columns (`variant.price`, `@_currency`). 4. **Map the columns — once.** An AI proposes a **MappingSpec**: a declarative JSON document saying which source column feeds which Lana offer field and which transforms to apply. The AI never writes or runs code; a deterministic executor applies the spec, and the identical executor powers the live sample preview in the browser, so what the merchant approves is exactly what gets signed. The merchant reviews and edits every line before confirming. A confirmed mapping is stored per supplier format fingerprint, so the next import of the same format needs no AI call at all. 5. **Preview and diff.** Every row is validated (title present, price parses and is plausible, currency is an ISO code, quantities are whole numbers). Then the import is compared against what this service has published before: rows are classified as new, updated, unchanged or archived, and the merchant sees those counts before anything is published. 6. **Images.** Product photo URLs from the file are fetched server-side, resized to a 1200px main image plus a 400px square thumbnail, and re-hosted content-addressed on the image server, so listings load fast and their images do not rot when the supplier moves or deletes the originals. A photo that cannot be fetched never blocks its product: the offer publishes without it and the import report says so. 7. **Sign and publish.** The browser signs every offer event with the merchant key, in batches, resumable. The server verifies each signed event against the template that was previewed — byte for byte — before queueing it, then publishes to the Lana relays with per-relay retry. ## Re-import behaviour (the part that matters most) Each row is given a **stable identifier derived from the merchant's own data**: d = sha256("lanafeed:v1:" + unit_id + ":" + external_id) truncated to 32 hex where `external_id` is the SKU / EAN / article-number column the merchant mapped. Because Lana offers are NIP-33 parameterised replaceable events keyed by that `d` tag: - Re-uploading tomorrow's export **updates** the same offers instead of creating duplicates. - Rows whose content did not change are **skipped entirely** — nothing is re-signed and nothing is re-published, so relays only ever see real changes. - Rows that disappeared from the file **can be archived** (the merchant chooses per import). Archiving republishes the offer with `status=archived`; it is never a NIP-09 deletion, so existing orders keep their reference. - Only offers this service itself published are eligible to be updated or archived. Anything the merchant created by hand in shop.lanapays.us is invisible to the import and cannot be touched by it. If the file has no stable ID column, the identifier falls back to the product title, and the interface warns that renaming a product will then create a new offer rather than update the old one. ## Event kinds published Offers are published as NIP-33 parameterised replaceable events. The kind is chosen by the business unit's category: 36500 Producer 36506 Furniture 36512 Service 36501 Café & Restaurant 36507 Pet 36513 Transport 36502 Shop 36508 Accommodation 36514 Online 36503 Kids 36509 Care/Beauty/Health/Wellness 36504 Construction 36510 Marketplace 36515 Other 36505 Fashion 36511 Body Arts & Movement 36516 B2B Tag skeleton of a published offer (identical to offers created by hand in the shop, by design): ["d", <32 hex, derived>] ["a", "30901::"] ["title", ...] ["type", "product" | "service" | "subscription" | "experience"] ["price", "", ""] ["unit", "piece" | "kg" | ...] ["status", "active" | "sold_out" | "seasonal" | "archived"] ... optional field tags (stock, sku, brand, eco, delivery, ...) ["image", ] ["thumb", ] (one pair per photo) ["payment", "lana_pay"] The event `content` is the plain-text product description. Calendar events (KIND 31923) are not part of bulk import. The full ecosystem kind specification lives at https://lananostr.site (machine-readable: https://lananostr.site/kinds.json). ## Trust model - The merchant's private key is used only inside their browser. The server never receives it, and never signs an offer. - The server holds one key of its own, used solely to upload images to the image server, which accepts uploads from that single key and no other. - Every signed event the server accepts is verified and matched against the template the merchant previewed before it is published. The server cannot publish something the merchant did not see. - Supplier image URLs are fetched behind an SSRF guard: public addresses only, standard HTTP(S) ports, revalidated redirects, size and time limits, and image content verified by magic bytes. ## What the AI in this service does and does not do - Does: read the column names and a sample of rows, and propose a MappingSpec. - Does not: execute code, transform data itself, publish anything, or see the merchant's key. The deterministic executor does the transforming; the merchant confirms the mapping; the browser does the signing. - Cost shape: one proposal per new supplier format. Repeat imports reuse the stored mapping and call no model at all. ## Endpoints an agent may read (no authentication) GET /api/public/info service descriptor, formats, limits, kinds GET /api/public/mapping-schema the MappingSpec DSL, transforms, target fields GET /api/system-params current relay list GET /health liveness Everything that mutates an import requires a NIP-98 signed request from the merchant's own key and is scoped to that merchant's jobs. ## Related services in the Lana network - https://shop.lanapays.us — where merchants define business units and where imported offers appear - https://pay.lanapays.us — e-commerce payment gateway - https://simple.lanapays.us — self-service merchant onboarding - https://blossom.lanapays.us — the image server used by this service - https://lananostr.site — Nostr kind documentation for the ecosystem