Authentication
How to authenticate — API keys for servers, a login token for mobile/native apps, and what to use where.
Authentication
Every request to https://api.ippo.one/v1 carries a Bearer token in the Authorization header:
Authorization: Bearer <token>There are two kinds of token. Pick by where the code runs.
| Your code runs on… | Use | Why |
|---|---|---|
| Your server (backend, cron, worker) | an API key (lp_live_…) | long-lived, created once, kept secret on the server |
| A mobile / native app | a login token (per user, per device) | the app never ships a shared secret; each user signs in |
| A browser SPA | call your own backend, which holds the API key | a lp_live_ key must never reach an untrusted client |
Both token kinds hit the same API and are scoped to the user's team.
Server-to-server — API keys
Create a key in the app (Settings → API keys), store it in your server's secrets, and send it as the Bearer token. See API keys.
curl https://api.ippo.one/v1/me -H "Authorization: Bearer $LOANPILOT_API_KEY"Never embed an API key in a mobile app or SPA
Anything shipped to a device or browser can be extracted. A leaked lp_live_ key acts as you until revoked.
Use the login-token flow below for apps, or proxy through your own backend.
Mobile / native apps — login token
The app signs the user in and gets a short-lived, revocable Bearer token. Store it in the device's secure
storage (iOS Keychain / Android Keystore) and send it as Authorization: Bearer <token>.
POST /v1/auth/token
Content-Type: application/json
{ "email": "user@example.com", "password": "…" }{ "token": "…", "token_type": "bearer", "expires_in": 86400,
"user": { "id": "…", "name": "…", "email": "…" } }- Send the
tokenas the Bearer on every subsequent call. - It expires (
expires_inseconds); when it does, sign in again. - Log out to revoke it immediately:
POST /v1/auth/logout
Authorization: Bearer <token>With the SDK:
import { LoanPilot } from '@ippopone/loanpilot'
const { token, client } = await LoanPilot.login({ email, password })
// persist `token` in secure storage; reuse it next launch:
const lp = new LoanPilot({ apiKey: savedToken })
await lp.logout() // revoke on sign-outSign-in is rate-limited
Repeated failures lock the account briefly and sign-in attempts are throttled per IP — the same protections as the web app.
Errors
401 — missing / invalid / expired / revoked token. 429 — rate-limited (back off and retry).