Let your favorite agents connect into Spotka.
One short key. It works with ChatGPT, Grok and Claude without any
code, and with plain curl if you prefer.
Just want to wire it into Claude, Cursor or another MCP app? That is a shorter page: spotka.co/mcp.
This works without a key and tells you everything the API can do right now:
curl https://spotka.co/api/v1
Point an assistant at that URL and it can work the rest out on its own.
Open Spotka on the web, Android or iPhone and go to Settings → API access → Create a key, or jump straight there:
You get a short key like spk_4KAS22M1JQFQ, and a
Copy for your assistant button. That button copies a ready-made block of
text. Paste it into ChatGPT, Grok or Claude and it explains the whole API to them. You do
not have to.
A key belongs to one person: yours. It can do only what you can do in the app yourself.
| do= | What it does | Options |
|---|---|---|
ideas | Things to do in the city, picked for you | limit |
events | Events other members are hosting that suit you. Filters narrow your own suggestions, not all of Spotka | limit, query, location, starts_after, starts_before, availability, page, cursor |
my_events | Events you host, events you joined, invitations waiting for you | limit |
create_event | Add an event | title (needed), when, where, about, max_guests, visibility, publish |
update_event | Change an event you host. Anything you leave out stays as it is, and nobody is notified. Pass publish=true to publish a draft | event (needed), title, when, where, about, max_guests, visibility, publish, expected_version |
invite | Invite people to an event | event and to, or the create_event options instead, to make the event and invite in one go |
join | Take a seat at someone else's event | event, note |
leave | Give up a seat you took | event |
respond | Accept or decline an invitation, or, as the host, approve a guest's pending time proposal (not interest alone; check allowed_actions first) | event, decision, guest |
event | One event in full: lifecycle, held seats vs calendared guests, guest states, seats remaining, allowed actions | event |
archive | Retire an event you host | event |
delete | Delete an unpublished draft | event |
profile | Your own profile, split into what other members see and your own private context | none |
update_profile | Change your own profile. Only the fields you name change | bio, city, interests, dietary_preferences, allergies, languages, current_focus and more |
notification_settings | Which notifications you get by push and by email, whether each is your own choice or the default, and how many devices are registered to receive them | app, channel |
update_notification_settings | Turn notifications on or off. Only the ones you name change, on every rail they travel on unless you say channel. default puts one back to what Spotka ships with | any notification key, plus all, type, enabled, channel, app |
calendar | What you have coming up: hosted and joined, soonest first. Events with no agreed time are kept separate | limit, from, to |
activity_history | What this API changed on your account. A record, not an undo log | limit, verb, since |
revoke_invite | Take back an invitation you sent. Email already sent cannot be unsent | invite |
inbox | Conversations with unread messages, and invitations waiting for an answer. Marks nothing read | limit |
conversation | One conversation. Does not mark it read | conversation, limit, before |
mark_read | Mark a conversation read, on purpose | conversation |
send_message | Send a message as you. Off unless your key has messaging enabled | body, and conversation or to=fern |
report_bug | Tell the Spotka team something is broken. Default is no auto-fix. Send autofix=true on a clear bug to send it to a coder. Duplicates fold onto the open report they match, so the same bug is not filed twice; send check_only=true to get that verdict without filing. Pass product_url, app_version, platform, and a screenshot when you have them. Poll report_status; when waiting_for_retest is true, re-test and call verify_bug | report (needed), title, screen, autofix, check_only, product_url, app_version, app_build, source_commit, platform, screenshot, screenshots |
report_feature | Ask for something Spotka does not do yet. A person reads it. Nothing is built automatically | report (needed), title, screen, product_url, app_version, app_build, source_commit, platform, screenshot, screenshots |
report_status | Poll a report this account filed: whether a fix has landed, and whether a re-test is waiting. Omit report to list recent ones. A fleet agent may pass waiting=true to list every report waiting for a re-test | report (number or id; optional), waiting (fleet agents only) |
verify_bug | Submit the retest verdict on a report this account filed, without the email token. Only when waiting for a re-test. A fleet agent may also verify any waiting report | report (needed), verdict (works, still_broken or unverified), note |
capabilities | What your key may do, what each verb changes in the world, and how much budget is left | none |
when=next Friday at 7pm or 2026-08-22T18:00:00+02:00.
An unreadable when= fails. Spotka works it out.
An idea from do=ideas carries when_time_known: when it is
false the when value gives only the day: the organiser has
not announced a start time, so do not present its 00:00 as one.
Four ways, all the same underneath. Use whichever your tool finds easiest.
curl -X POST https://spotka.co/api/v1 \
-H 'X-API-Key: spk_XXXXXXXXXXXX' \
-d 'do=my_events'
curl -X POST https://spotka.co/api/v1 \
-H 'X-API-Key: spk_XXXXXXXXXXXX' \
-H 'Content-Type: application/json' \
-d '{"do":"ideas"}'
curl 'https://spotka.co/api/v1?key=spk_XXXXXXXXXXXX&do=ideas'
curl -H 'X-API-Key: spk_XXXXXXXXXXXX' https://spotka.co/api/v1/events/mine
curl -X POST -H 'X-API-Key: spk_XXXXXXXXXXXX' \
-d '[email protected]' https://spotka.co/api/v1/events/<id>/invite
A header (X-API-Key or
Authorization: Bearer) is the preferred way to send your key. A key in a
link or body field can end up in server logs, so treat any such URL like a password.
The key parameter still works for tools that can only send a URL.
curl -X POST https://spotka.co/api/v1 \
-H 'X-API-Key: spk_XXXXXXXXXXXX' \
-d 'do=create_event' \
-d 'title=Sunday board games' \
-d 'when=Sunday at 6pm' \
-d 'where=Kawiarnia Relaks'
The reply tells you the time that was actually saved. If the time you wrote was not
understood, or publish=true could not complete, the call fails
(ok: false) and names the unmet fields. It does not leave a silent draft
that looks like success.
Add publish=false to leave it as a draft. To publish that draft later, send do=update_event with the event id and publish=true.
Everything above is also available as MCP tools, so apps that speak MCP can use Spotka directly, with no copy-pasting of instructions.
claude mcp add --transport http spotka https://spotka.co/api/v1/mcp \
--header "X-API-Key: spk_XXXXXXXXXXXX"
The MCP endpoint is https://spotka.co/api/v1/mcp. Same key,
same limits. Setup for Claude Desktop, Cursor and the rest is on
spotka.co/mcp.
Every interesting flow in Spotka needs two people: someone hosting and someone joining. A normal key is one person, so for testing there is a second kind: a test key, which an admin can create for you.
Add as=<name or email> to any call and it runs as that
account. do=actors lists the ones you can use. These are
practice accounts only. A test key can never act as a real member, and it
can never send email to anyone outside them.
Normally making an event goes through the same writing help the app
uses, which takes a few seconds and words things differently each time.
Add raw=true, together with starts_at as an ISO
time like 2026-10-05T17:00:00Z, and the fields are saved
exactly as you wrote them, straight away, so you can check the result.
It still goes through the app's real creation path, so the event ends up properly formed and can be found by matching. Only the writing model is skipped.
Spotka asks a member to publish some of their own events before they can
join anyone else's. do=seed tops a test account up to that
number, so the rule is met rather than worked around.
The reply includes deck_size, how many suggestions that
member currently has, which tells you whether a join will go through the
normal suggestions list or fall back to the share-link route.
do=reset retires every event that key made. Run it at the
end and a test leaves nothing behind.
A test key can also mint, list and revoke standard keys for
agent testers (and consim accounts) so a four-actor invite suite does not
need four Chrome profiles. Name the owner with for= as an
email or id, never a display name. The verbs are key_list,
key_create and key_revoke. The secret from
key_create is shown once; listing returns only the prefix
and dates. A test key cannot set test_mode on what it mints
(that stays an admin sign-in action). A standard key cannot call these
at all.
# list grokbot2's keys (prefix only)
curl -X POST https://spotka.co/api/v1 \
-d 'key=YOUR_TEST_KEY' -d 'do=key_list' -d '[email protected]'
# mint a standard key for that account; the secret is in the reply once
curl -X POST https://spotka.co/api/v1 \
-d 'key=YOUR_TEST_KEY' -d 'do=key_create' -d '[email protected]'
# revoke one
curl -X POST https://spotka.co/api/v1 \
-d 'key=YOUR_TEST_KEY' -d 'do=key_revoke' -d '[email protected]' \
-d 'id=<key-id>'
# the host makes an event and publishes it
curl -X POST https://spotka.co/api/v1 \
-d 'key=YOUR_TEST_KEY' -d 'as=bartek@…' -d 'do=create_event' \
-d 'raw=true' -d 'title=Board games' -d 'starts_at=2026-09-12T17:00:00Z'
# somebody else joins
curl -X POST https://spotka.co/api/v1 \
-d 'key=YOUR_TEST_KEY' -d 'as=kacper@…' -d 'do=join' -d 'event=<id>'
# -> "via": "deck" joined from their suggestions, the normal way
# -> "via": "share_link" matching did not suggest it, so the link was used
# the host checks it worked
curl -X POST https://spotka.co/api/v1 \
-d 'key=YOUR_TEST_KEY' -d 'as=bartek@…' -d 'do=event' -d 'event=<id>'
# -> "guests": 1
# tidy up
curl -X POST https://spotka.co/api/v1 -d 'key=YOUR_TEST_KEY' -d 'do=reset'
The same thing works through MCP, so you can also just ask Claude to try things and tell you what breaks.
report_bug and report_feature are the same
verbs a member's assistant uses. On a test account they file immediately:
no confirmation, and they land in the review queue tagged as a
test report. Default is no auto-fix. Send autofix=true on a
clear bug to send it to a coder. Feature requests still wait for a
person. The in-app Report a bug / Request a feature screens do the same
thing when you are signed in as that account.
A bot cannot click the verification email. Close the loop from a
spk_ key. Do not read the mailbox, and do not wait
on that mail. A regular member key still only sees reports it filed. A
QA fleet agent key can also re-test a report another person filed: poll
report_status with waiting=true, then call
verify_bug on that number after a real check. Do not wait
for the original reporter.
report_bug. Keep report.number
from the reply. Pass product_url, app_version,
platform, and a screenshot when you have them.report_status (that number, or omit it to list
recent filings). When waiting_for_retest is true, re-test
the original repro on production.verify_bug with verdict=works if it
is fixed, or still_broken to reopen the report. If you could not run
the re-test at all (the screen would not open, or the thing the repro
needs was not there), send verdict=unverified instead.
That changes nothing and leaves the report waiting, which is the
honest answer. Never guess still_broken for a repro you could not
run.# file (keep report.number from the JSON). Default is no auto-fix.
curl -X POST https://spotka.co/api/v1 \
-H 'X-API-Key: YOUR_KEY' \
-d 'do=report_bug' \
-d 'title=People from events is not available yet' \
-d 'report=Opening People from an event card shows not available yet. I expected the guest list.' \
-d 'product_url=https://spotka.co/app/events' \
-d 'platform=web'
# poll that filing (REPORT_NUMBER is report.number from the file reply)
curl -X POST https://spotka.co/api/v1 \
-H 'X-API-Key: YOUR_KEY' \
-d 'do=report_status' -d 'report=REPORT_NUMBER'
# omit report= to list this account's recent filings instead
# fleet agent keys: omit report= and pass waiting=true to list every report waiting for a re-test
# after re-testing production, when waiting_for_retest is true
curl -X POST https://spotka.co/api/v1 \
-H 'X-API-Key: YOUR_KEY' \
-d 'do=verify_bug' -d 'report=REPORT_NUMBER' -d 'verdict=works'
Every failure comes back in the same shape, written to be read rather than decoded:
{
"ok": false,
"error": "event_required",
"message": "Name the event to invite people to.",
"hint": "Send event=<event id>, or title=… to create one and invite in the same call."
}
Reading takes about three to five seconds. Asking for other members' events can take about seven the first time, because it waits for your matches to be worked out rather than handing back an empty list. Making an event takes about fifteen: it goes through the same writing help the app uses.
What you have left is in the X-RateLimit-Remaining header of
every reply, and X-RateLimit-Bucket names which of the budgets above it
is counting. The reply always shows the one you are closest to using up, usually
the per-minute one. If you need more, write to
support@spotka.co.
They go out in your name, so it is worth telling your assistant to check with you before it invites anyone. The block the app copies for you already asks it to.