API documentation
Everything apps can do with TKDchecker, version 1. JSON over HTTPS.
Base URL
https://www.tkdchecker.com//api/v1 · Machine-readable: OpenAPI
Two kinds of access
- Public data: academies, schedules, events and public profiles. Send your app's client id in the X-Client-Id header.
- For a member: their own data and everything that writes. The member signs in on TKDchecker and allows your app (OAuth 2.0, authorization code with PKCE). You get an access token for one hour and a refresh token.
curl https://www.tkdchecker.com//api/v1/academies?q=gracie \ -H "X-Client-Id: bcapp_your_client_id"
Signing a member in
1. Send the member to the authorize page with a code challenge (S256):
https://www.tkdchecker.com//oauth/authorize?response_type=code &client_id=bcapp_your_client_id &redirect_uri=https://yourapp.com/callback &scope=profile:read%20training:write &state=random_value &code_challenge=BASE64URL(SHA256(verifier)) &code_challenge_method=S256
2. The member allows the app and comes back to your redirect URI with ?code= and your state. 3. Exchange the code:
curl -X POST https://www.tkdchecker.com//oauth/token \ -d grant_type=authorization_code \ -d code=THE_CODE \ -d redirect_uri=https://yourapp.com/callback \ -d client_id=bcapp_your_client_id \ -d client_secret=YOUR_SECRET \ -d code_verifier=THE_VERIFIER
Mobile and browser apps register as public clients: they have no secret and must use PKCE. Refresh with grant_type=refresh_token (the refresh token changes every time). Revoke with POST /oauth/revoke.
curl -X POST https://www.tkdchecker.com//api/v1/me/training \
-H "Authorization: Bearer ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: 6f1c2e" \
-d '{"date":"2026-10-01","type":2,"minutes":90,"rounds":6,"style":"gi"}'Scopes
profile:readSee your profile, belt, promotion history and verification statustraining:readSee your training log and check-instraining:writeLog training for you, and edit or delete the sessions this app logged needs approvalcheckins:writeCheck you in to classes at your academies needs approvalevents:writeMark events you are going to needs approvalclub:attendanceRegister attendance at academies you run, for members who allowed this app needs approval
Write scopes are open to an app once we have approved it: ask on your app's page. Apps can never vote, change belts, promotions or verification, send messages or touch payments.
Limits
- 10,000 calls a day per app (more on request) and 120 a minute per member or IP.
- Responses carry X-RateLimit-Limit and X-RateLimit-Remaining. Over the limit you get 429.
- Lists are paged: pass next_cursor back as ?cursor= until it is null.
- Send an Idempotency-Key header with writes: a retry with the same key never writes twice.
Errors
{"error": {"code": "insufficient_scope", "message": "The token lacks the 'training:write' scope."}}Privacy
Public data only shows adults with a public profile who have not turned off "Show me in apps". Use the data only for what the member allowed, and delete it when they disconnect your app.
Your member
/me profile:readThe member: name, belt, verification, academy
/me/promotions profile:readPromotion history (belts, dates, promoters)
/me/academies profile:readAcademies the member belongs to
/me/events profile:readEvents the member is going to or interested in
Training log
/me/training training:readTraining sessions and check-ins, newest first
?since | From date, YYYY-MM-DD |
?until | To date, YYYY-MM-DD |
?limit | Results per page, 1-100 (default 25) |
?cursor | next_cursor from the previous page |
/me/training training:writeLog a training session
date | YYYY-MM-DD (required) |
type | Id from /training-types (default 2, class) |
minutes | 0-1440 |
rounds | 0-100 |
style | 'gi' or 'nogi' (ignored: this site has no gi/no-gi) |
note | Up to 10000 characters |
/me/training/{id} training:readOne session
/me/training/{id} training:writeChange a session this app logged
date | |
type | |
minutes | |
rounds | |
style | |
note |
/me/training/{id} training:writeDelete a session this app logged
/me/checkins checkins:writeCheck in to one of today's classes (from an hour before until 30 minutes after it)
academy_id | Academy id (required) |
class_id | Class id from /academies/{id}/schedule (required) |
/training-types publicTraining types an app may log
Academies
/academies publicSearch academies
?q | Name, city or affiliation |
?country | Country name |
?limit | Results per page, 1-100 (default 25) |
?cursor | next_cursor from the previous page |
/academies/{id} publicOne academy
/academies/{id}/schedule publicWeekly class schedule
/academies/{id}/members publicMembers with public profiles
?limit | Results per page, 1-100 (default 25) |
?cursor | next_cursor from the previous page |
Club attendance
/academies/{id}/consents club:attendanceMembers who allowed this app to register their attendance, and the link to share with the others
/academies/{id}/attendance club:attendanceA day's attendance
?date | YYYY-MM-DD (default today) |
/academies/{id}/attendance club:attendanceRegister attendance for a member who allowed it (the token belongs to an admin or coach of the academy)
member_id | Member id (required) |
class_id | Class id (optional) |
date | YYYY-MM-DD, up to 14 days back (default today) |
note | Up to 500 characters |
Members
/members publicSearch members with public profiles
?q | Name, at least 2 characters |
?limit | 1-50 (default 20) |
/members/{id} publicA public profile
/members/{id}/promotions publicA public profile's promotion history
Events
/events publicEvents
?when | 'upcoming' (default) or 'all' |
?country | Country name |
?type | 1 seminar, 2 competition, 3 training camp, 4 other |
?limit | Results per page, 1-100 (default 25) |
?cursor | next_cursor from the previous page |
/events/{id} publicOne event
/events/{id}/rsvp events:writeSet the member's answer
status | 'going', 'interested', 'not_going' or 'none' |
Reference
/belts publicAll belts and degrees


