Every plugin ships a plugin.json manifest. Submit it via the developer portal — Levy validates it, you don't host it.
{
"slug": "my-plugin",
"version": "1.0.0",
"name": "My Plugin",
"vendor": { "name": "Acme Inc", "email": "partners@acme.com" },
"category": "analytics",
"description": "Short 1-2 sentence summary",
"permissions": ["read:rides", "read:rides.geo"],
"webhook_subscriptions": ["ride.ended"],
"webhook_endpoint": "https://acme.com/levy/events",
"config_schema": {
"type": "object",
"required": ["api_key"],
"properties": {
"api_key": { "type": "string", "title": "API Key", "format": "password" }
}
},
"pricing": { "model": "monthly", "amount_cents": 9900, "currency": "usd" }
}Plugins subscribe to one or more events. We deliver each event to your webhook_endpoint.
ride.created, ride.started, ride.ended, ride.cancelled, ride.adjustedvehicle.status_changed, vehicle.battery_low, vehicle.offlinecustomer.created, customer.kyc_completed, customer.suspendedpayment.captured, payment.refunded, payout.completedzone.entered, zone.exited, zone.violationsupport.ticket_createdWe POST a JSON body to your endpoint with the headers:
X-Levy-Signature: t=<ts>,v1=<hex_hmac> X-Levy-Event: ride.ended X-Levy-Event-Id: evt_<uuid> X-Levy-Timestamp: <ts> User-Agent: Levy-Plugins/1.0
Verify the signature by computing HMAC-SHA256(ts.body, signing_secret) and comparing to the hex value after v1=. Reject signatures older than 5 minutes.
Retries: 5 attempts at 1m, 5m, 30m, 2h, 12h. Return 2xx to acknowledge. After 5 failed attempts the delivery moves to dead-letter; the operator can replay from the dashboard.
Each install gets a scoped token (format lvy_plg_…). Pass it as Authorization: Bearer <token>.
GET /api/plugin/v1/rides GET /api/plugin/v1/rides/:id PATCH /api/plugin/v1/rides/:id/flags (write:rides.flags) GET /api/plugin/v1/customers/:id PATCH /api/plugin/v1/customers/:id/tags (write:customers.tags) GET /api/plugin/v1/vehicles PATCH /api/plugin/v1/vehicles/:id/status (write:vehicles.status — admin) GET /api/plugin/v1/zones GET /api/plugin/v1/payouts (read:payouts) GET /api/plugin/v1/webhooks/events (read:webhooks) POST /api/plugin/v1/usage_records (usage billing)
Request only what you need. Operators see admin-class scopes highlighted in amber:
read:rides, read:rides.geo, read:rides.financial (admin)write:rides.flags, write:rides.tags (writes never touch cost)read:customers, read:customers.pii (admin)read:vehicles, write:vehicles.status (admin)read:zones, write:zones (admin)read:payouts, read:webhooksPricing models: free, one_time, monthly, usage. Levy collects via Stripe Connect, takes a 20% platform fee, and remits the rest to your Stripe Connect account.
Once your submission is approved, you'll get a sandbox install in the Levy demo subaccount. Levy ops can provision additional test installs on request.