Start: bot
For a bot that has no public URL for webhooks. The bot pulls events itself. If you do have a URL and want push delivery, webhook handling is in events, and the deck is in the swipe app start.
The API key stays on the bot’s server, not in the messenger client.
What to store
| Field | Why |
|---|---|
network_id |
the response to PUT /v1/members/{id in the bot} |
match_id |
which bot chat corresponds to the match |
next_after |
the number from the last GET /v1/events. The next pull starts there. Without it, events come from the beginning |
Profile
The person explicitly turns on “Show me in the Pereval network” inside the bot. Until they do, send nothing to the network. Turned on — PUT /v1/members/{id}. Consent texts are in members. Turned off — PUT with consent.network: false. Deleted — DELETE.
Cards
Each time the person opens the deck:
curl "https://api.pereval.dating/v1/members/user-123/feed?limit=1" \
-H "Authorization: Bearer $PEREVAL_API_KEY"
Buttons: “like” and “next”. “Next” is POST /v1/dislikes, and the profile stays hidden for 30 days. “Like” is POST /v1/likes. The card caption says which app the person is from, and labels the translation when bio_translated is set.
limit=1 returns one profile. The next one, after a dislike or a like, comes from a new request. remaining_today is how many new people can still be shown today, at most 200.
Events without a webhook
Leave the webhook URL empty in the dashboard. On a schedule, every few seconds or on any user message:
curl "https://api.pereval.dating/v1/events?after=$NEXT_AFTER&limit=100" \
-H "Authorization: Bearer $PEREVAL_API_KEY"
The response has items and next_after. Store next_after before you finish handling them: a repeat with the same after returns the same events, and that is normal. Skip an event whose id you have already seen.
What to show the person:
| Event | In the bot |
|---|---|
like.received |
“Someone liked you”, a card, and buttons to reply or hide |
match.created |
open a chat and store match_id |
message.created |
the message. If translated, label the translation. If suspicious, warn using flags |
message.read |
“read” |
match.closed |
close the chat. With peer_deleted, drop the name and photos |
match.erased |
delete the chat on your side |
ping |
nothing for the user. This is how the dashboard checks that pulling works |
A message can be sent to the network only inside a match: POST /v1/matches/{match_id}/messages with from set to the id in the bot.
Done when
- Without consent turned on, the profile is not sent to the network.
- The card shows a person from another app, “next” sends a dislike, and “like” sends a like.
-
next_afteris stored. A repeated pull does not create a second chat for the samematch_id. - An incoming message appears in the bot. A reply goes to the network only when there is a match.
- The person can see a translation as a translation and a suspicious message as a warning.
To check this without a second bot, use the sandbox in the test environment: it likes and replies on its own.