https://github.com/ReverserID/Mamikos-Unofficial-API/
Typed TypeScript client for kay.mamikos.com, the private API behind the
Mamikos Android app (com.git.mami.kos, build 26.18.0 / 1226180011).
- Every endpoint discovered in the wild, typed, and documented
- Body-level AES-256-CBC handled transparently
- Authenticated calls signed with the right
Authorization header
- Pluggable cipher / signer so the client survives future key rotations
No SDK was harmed in the making of this client.
Crypto, in one paragraph
Every body to and from kay.mamikos.com is wrapped as {"data":"<base64>"}.
The inner bytes are AES-256-CBC with NoPadding, 16-byte UTF-8 IV. The
client encrypts and decrypts these wrappers transparently — you only ever
deal with typed JavaScript objects.
A few endpoints — notably /api/v3/suggestion and /api/v3/suggestion/prime
— return plaintext. The client auto-detects: if the response JSON has a
data string field it decrypts, otherwise it returns the parsed body as-is.
Authenticated requests carry Authorization: GIT <hmacSha256Hex>:<userId>.<sessionToken>.
The HMAC pre-image and secret are baked into src/signer.ts and src/config.ts.
Endpoint catalogue
Auth (no signature, encrypted body)
| Method | Path | Notes |
| POST | /api/v2/auth/tenant/register?v=2 | rate-limit 60/min |
| POST | /api/v2/auth/code/request | OTP send, 2/min |
| POST | /api/v2/auth/code/check | OTP verify, 10/min |
| POST | /api/v2/auth/tenant/login | returns {user, token} |
| POST | /api/v2/auth/logout | authenticated |
| POST | /api/v3/device-token/refresh | empty {} body, authenticated |
Profile / housekeeping (signed)
/api/v2/user/profile, /api/v2/user/edit, /api/v2/user/update,
/api/v2/notifications/counter, /api/v2/user/voucher/count,
/api/v3/user/tier/status, /api/v2/user/point/total,
/api/v2/app/version, /api/v3/user/agreement?type=tenant_privacy_policy,
/api/v2/home, /api/v2/user/booking/home-shortcut,
/api/v2/user/contract-submission/shortcut, /api/v2/flash-sale/running,
/api/v2/area/campus?top=true, /api/v3/homepage/version/latest,
/api/v3/tracker-session/active.
Search / discovery
| Method | Path | Notes |
| GET | /api/v3/suggestion?keyword=<q> | plaintext |
| GET | /api/v3/suggestion/prime?keyword=<q> | plaintext |
| GET | /api/v2/room/{slug}?query=<q> | encrypted |
| POST | /api/v2/stories/list | with ?query= or ?with_thematic_badge=true |
| GET | /api/v2/stories/{id}?query=<q> | |
| GET | /api/v2/stories/{id}/{gallery,owner,rules,recommendation} | |
| GET | /api/v2/stories/meta/{id}?v=2&tenant_id=<id> | |
| GET | /api/v2/stories/location/{id} | |
| POST | /api/v2/stories/{id}/view | |
| POST | /api/v2/stories/{id}/{call,call/reply} | authenticated |
| GET | /api/v2/stories/chatboot?query=<q> | |
Kost detail
| Method | Path |
| GET | /api/v3/kost/{id}/benefit |
| GET | /api/v3/kost/{id}/special-rule |
| GET | /api/v3/kost/{id}/facility/{room_specification,room_facilities,public_facilities,parking_facilities,bathroom_facilities} |
| GET | /api/v3/room/{id}/near-landmark?sort=PRIORITY&limit_each_type=true |
| GET | /api/v3/room/{id}/owner/last-seen |
| GET | /api/v3/property/{propertyId}/kost?current_kost=<id>&limit=9&offset=0 |
Booking — ajukan sewa chain (authenticated, encrypted)
GET /api/v2/user/booking/detail-room/{roomId} — booking-form prefill
GET /api/v2/user/booking/draft-price/{roomId} — quoted price
GET /api/v3/room/{roomId}/additional-fees?limit=100 — extras
POST /api/v2/user/booking/estimate-checkout — confirms total
POST /api/v2/user/draft-booking — the actual ajukan sewa submit
MamikosClient.draftBooking(...) only fires step 5. Call the rest first if you
want to reproduce the in-app pricing UI faithfully.
Headers (auto-injected)
user-agent: mamikos/com.git.dabang/26.18.0/1226180011 Dalvik/2.1.0 (Linux; U; Android 9; ...)
x-git-time: <unix-seconds>
x-git-pf: app
authorization: GIT <hmacSha256Hex>:<userId>.<sessionToken> (when authenticated)
content-type: application/json (only when body present)
accept-encoding: gzip
Server rate-limits live in x-ratelimit-* response headers — most endpoints
are 60/min, OTP request is 2/min, OTP check is 10/min. The client does
not auto-throttle; budget your calls.
Quick start
git clone https://github.com/reverserid/MamiKos.git
cd MamiKos
npm install
copy .env.example .env
notepad .env
CLI:
npm run cli -- suggest --keyword bogor
npm run cli -- home
npm run cli -- kost --id 23580357
npm run cli -- otp-request
npm run cli -- otp-check
npm run cli -- login
npm run cli -- profile
npm run cli -- book --room 76680378 --checkin 2026-06-01 --name "Imtaqin" --dry-run
Programmatic:
import { MamikosClient } from "./src/client.js";
import { buildClientOptions } from "./src/config.js";
const client = new MamikosClient(buildClientOptions());
const hits = await client.suggest("yogyakarta");
for (const land of hits.suggestion.landings) console.log(land.title, land.slug);
const detail = await client.storyById(23580357);
console.log(detail);
Caveats
- Authenticated endpoints expect
Authorization: GIT <sig>:<userId>.<token>
where <sig> is HmacSHA256-hex over a server-defined pre-image. The default
buildPreimage follows <x-git-time>|<METHOD>|<path+query>|<body> —
re-confirm if you hit 401s on a known-good token.
- Mamikos pads with NUL bytes when the plaintext is not block-aligned. The
client trims everything after the last } or ] before parsing. If you
call an endpoint that returns a non-JSON body, set rawResponse: true on
the internal call(...).
- Never commit
.env, HTTP Toolkit .har exports, or anything containing
decrypted user data.