# Vakantio > Vakantio is where travelers keep a running journal of a trip — posts, > photos, an itinerary on a map — and decide who sees it. A blog at > https://vakantio.de can be open to the whole web, or limited to a > follower list so friends and family can follow along in real time > without anything being indexed publicly. Anything a human can do on > the site, an agent can do programmatically via the official CLI > (`@vakantio/cli`) or TypeScript SDK (`@vakantio/sdk`). Reading public posts is open and unauthenticated. Authoring (creating posts, drafts, trips, comments, follows, bookmarks) and reading follower-only content requires a session. The API is served at `https://api.vakantio.de`. ## CLI quickstart ```sh npm i -g @vakantio/cli vakantio login # opens browser, persists ~/.vakantio/config.json vakantio whoami # confirms the session works vakantio search "tuscany" --json # every command supports --json ``` ## Login from a sandbox / container / agent If you're running in an environment that can't accept a `127.0.0.1` OAuth callback (ChatGPT Code Interpreter, Codex sandbox, GitHub Codespace, CI runner, plain SSH session, Docker container, etc.), use the device flow: ```sh vakantio login --device ``` The CLI prints a URL and a short code (e.g. `BCDF-9X4P`). Relay both to the user — they open the URL on whatever device they're already signed into Vakantio on (laptop, phone, doesn't matter), enter the code, click Approve. The CLI is polling in the background; once the user approves, the next poll succeeds and `vakantio login` exits with the session saved. No callback URL, no copy-paste of secrets back into the chat. The CLI auto-detects most sandboxed environments (no `DISPLAY`, `$CI`, `$CODESPACES`, `$CONTAINER`, no TTY on stdout) and falls back to the device flow without `--device`. Set `VAKANTIO_FORCE_LOOPBACK=1` to override that auto-detection, or `VAKANTIO_DEVICE_FLOW=1` to force the device flow even on a normal laptop. If even printing the URL is awkward (you already have a long-lived session for this user from elsewhere), pass it via `VAKANTIO_SESSION_ID` instead and skip `vakantio login` entirely. Every command accepts `--json` (machine-readable output) and `--profile ` (alternate `~/.vakantio/.json` config, for juggling multiple accounts). Auth-required commands are marked **(auth)** below. ## Commands ### Auth - `vakantio login` — browser OAuth (loopback callback); stores `sessionId` at `~/.vakantio/config.json` - `vakantio login --device` — RFC 8628 device flow; use this in any environment that can't accept a `127.0.0.1` callback (sandboxes, containers, Codespaces, CI, headless SSH). The CLI prints a URL + short code; the user opens the URL on a device they're already signed into Vakantio on, enters the code, clicks Approve. No callback URL or copy-paste of secrets required. - `vakantio logout` — clear the local session - `vakantio whoami [--refresh]` **(auth)** — show / re-fetch the current user ### Posts and drafts - `vakantio posts list [--page N] [--tags ...] [--destination ] [--locale de|en]` — public feed - `vakantio posts get [--draft]` — single post (drafts require auth) - `vakantio posts create --title [--content ] [--tags ...] [--lat --lng] [--date-traveled ] [--media ...] [--trip ]` **(auth)** — `--media` accepts images and videos; on `posts update` the new files are appended to the existing media list rather than replacing it - `vakantio posts update [...same flags]` **(auth)** - `vakantio posts publish ` / `vakantio posts unpublish ` **(auth)** - `vakantio posts delete ` **(auth)** — drafts only - `vakantio posts like|unlike|bookmark|unbookmark ` **(auth)** - `vakantio drafts list` **(auth)** — drafts on the active blog ### Blogs (a "blog" is one user's travel journal) - `vakantio blogs list` **(auth)** - `vakantio blogs create --name [--description ] [--locale de|en] [--instagram ] [--image ] [--header-image ] [--switch]` **(auth)** - `vakantio blogs switch ` **(auth)** — set the active blog for write commands - `vakantio blogs get []` — blog metadata (defaults to active blog) - `vakantio blogs stats []` **(auth)** — view counts, top posts - `vakantio blogs update [--name] [--description] [--image ] [--header-image ] [--instagram ] [--locale de|en]` **(auth)** - `vakantio blogs follow ` / `vakantio blogs unfollow ` **(auth)** ### Destinations, search - `vakantio destinations list [--parent ] [--type country|state|city] [--limit N]` - `vakantio destinations get ` - `vakantio destinations search "" [--limit N]` — find a destination by name - `vakantio search "" [--limit N]` — full-text across posts, blogs, destinations - `vakantio search [""] --lat N --lng N [--radius-km 50]` — geo-scoped post search; `` is optional, so bare geo works too Media uploads happen via `posts create/update --media ` (and the blog-avatar `blogs create/update --image --header-image ` flags). There is no standalone `vakantio media upload` command. ### Trips, comments, notifications - `vakantio trips list|get|create|update|delete` (writes **auth**) - `vakantio comments list ` / `vakantio comments create --text ` **(auth for writes)** - `vakantio notifications list [--unread]` / `vakantio notifications mark-read [...]` **(auth)** ## SDK direct use The CLI is a thin wrapper around `@vakantio/sdk`; every command maps 1:1 to an SDK call. To call the API directly from TypeScript: ```ts import { createVakantio } from "@vakantio/sdk"; const vak = createVakantio(process.env.VAKANTIO_SESSION_ID); const posts = await vak.posts.list({ tags: "thailand" }); ``` ## Identify your client The CLI and SDK already send a structured `User-Agent` plus an `X-Vakantio-Client` header that name the tool, its version, and the runtime. If you're calling the API yourself (curl, fetch, your own wrapper), please send a `User-Agent` that names your tool and gives a contact path. Good examples: ``` User-Agent: my-blog-importer/0.3 (+https://github.com/me/my-blog-importer) User-Agent: agentname-research/2026-05 (contact: ops@example.com) ``` Requests without a User-Agent, or with a generic `curl` / `bot` / `crawler` / `scraper` string, may be rejected with HTTP 403. ## Also available - [vakantio.de/llms.txt](https://vakantio.de/llms.txt) — this body, served as `text/plain` per the llms.txt spec - [vakantio.de/skill.md](https://vakantio.de/skill.md) — this body wrapped in Claude Skills / Cursor Agent Skills YAML frontmatter, served as `text/markdown` for direct ingestion as an agent skill - [vakantio.de/robots.txt](https://vakantio.de/robots.txt) — crawler rules