* docs: migrate from mkdocs to mdbook - Rename old mkdocs docs/ to old-docs/ for reference - Set up new docs/ with mdbook (book.toml + src/ tree) - Mirror full nav structure from mkdocs.yml into SUMMARY.md - Add Justfile-docs with docs-serve, docs-build, docs-check, docs-install recipes - Import Justfile-docs from root Justfile - Rewrite .github/workflows/docs.yml: build step uses taiki-e/install-action to install mdbook, split into separate build + deploy jobs, PR builds run the check step too * ci(docs): pin actions to SHAs, install mdbook via release binary * ci(docs): install mdbook from apt instead of curling a release binary * dev: replace mkdocs python stack with mdbook in dev image * ci(docs): apt only works on Debian; restore release binary install for Ubuntu CI * docs: fix duplicate file entries in SUMMARY.md * docs: remove docs-install recipe * docs: remove site-url from book.toml to fix asset loading * dev: install mdbook from upstream release binary, not Debian apt The Debian package (0.4.x+ds) strips bundled font assets, leaving the built site without fonts/fonts.css. Use the upstream tarball (same as CI) so the theme is complete. Handles x86_64 and aarch64. * docs: vendor mdbook tarballs in dev/mdbook/, install from there Dockerfile.dev uses COPY + tar to install the right arch at build time. CI extracts the x86_64 tarball directly from the checkout. No network access required for either — and no stripped-fonts Debian package. * fix: unwritten
7.7 KiB
Import Scores
Import scores from a file.
POST /api/v1/import/file
Perform a score import that depends on a file, such as a .csv import.
Permissions
submit_score
Parameters
This endpoint expects data in multipart/form-data form.
This is because we're handling file imports, and is the
appropriate way to send files.
| Property | Type | Description |
| :: | :: | :: |
| importType | String | The ImportType this import is for. This only accepts file/ ImportTypes. |
| scoreData | File | The file to import scores from. |
| HTTP Header | Description |
| :: | :: |
| X-User-Intent (optional) | If this header is "true", the request is assumed to have been sent with 'User Intent'. For more on this, see Import Types |
!!! info It's the responsibility of the API user to use the X-User-Intent header properly. It should only be used when the user has explicitly requested this import (i.e. not sent by an automated script).
Response
Implementation Dependent. There are two reponse scenarios for this endpoint, depending on whether the server uses an external score processor or not.
External Score Processor Response
If an external score processor is being used, 202 is returned as a status code, and you are given the following:
| Property | Type | Description |
| :: | :: | :: |
| url | String | A URL to poll for information about this import, while it's being processed. |
| importID | String | The ID of the import currently being processed. |
Internal Score Processor Response
If score processing is not done externally, the following is returned:
| Property | Type | Description |
| :: | :: | :: |
| <body> | ImportDocument | The import document created as a result of this import. |
Example
Request
POST /api/v1/import/file
// this is not actually a multipart http request example
// as those are huge.
importType="file/eamusement-iidx-csv"
scoreData=<file data>
Response
{
"importType": "file/eamusement-iidx-csv",
"idStrings": [
"iidx:SP"
],
"scoreIDs": [
"R6fad5f4947454d8238b45d6a1255d63be4da1130bf91fe9d05df29765a148da8"
],
"errors": [],
"importID": "bea63277b54a5846bab1fd3a6ce54bfd41276857",
"timeFinished": 1623352263023,
"timeStarted": 1623352260445,
"createdSessions": [
{
"sessionID": "Qb336d6b1cc0930747f161769a13238a41dce0004",
"type": "Created"
}
],
"userID": 1,
"classDeltas": [],
"goalInfo": [],
"questInfo": [],
"userIntent": false, // if X-User-Intent was set, this would be true.
}
OR
{
url: "https://boku.tachi.ac/api/v1/imports/SOME_IMPORT_ID/poll-status",
importID: "SOME_IMPORT_ID"
}
Synchronise scores up with an API.
POST /api/v1/import/from-api
This endpoint requests scores from an API to sync up with the requesting user's profile. This can
be performed programmatically, as long as the key has submit_score permissions.
!!! note The user must configure integration with these services up.
Permissions
submit_score
Parameters
| Property | Type | Description |
| :: | :: | :: |
| importType | Any Supported API Import Type | The importType this synchronisation is for. |
Response
Implementation Dependent. There are two reponse scenarios for this endpoint, depending on whether the server uses an external score processor or not.
External Score Processor Response
If an external score processor is being used, 202 is returned as a status code, and you are given the following:
| Property | Type | Description |
| :: | :: | :: |
| url | String | A URL to poll for information about this import, while it's being processed. |
| importID | String | The ID of the import currently being processed. |
Internal Score Processor Response
If score processing is not done externally, the following is returned:
| Property | Type | Description |
| :: | :: | :: |
| <body> | ImportDocument | The import document created as a result of this import. |
Example
Request
POST /api/v1/import/from-api
{
importType: "api/flo-iidx"
}
Response
See previous example.
Force Tachi to reprocess your orphanned scores.
POST /api/v1/import/orphans
This endpoint goes through all of the requesting user's Orphanned Scores and attempts to find them a parent song & chart.
!!! note Scores automatically attempt de-orphaning every day at 1 AM UTC on Kamaitachi and Bokutachi, this endpoint just allows you to force a deorphaning, should you wish to.
Permissions
- submit_score
Parameters
None.
Response
| Property | Type | Description |
| :: | :: | :: |
| processed | Integer | The amount of orphans processed. |
| failed | Integer | The amount of orphans that did not find a parent chart, and were kept as orphans. |
| success | Integer | The amount of orphans that successfully found a parent chart, and were turned into real scores. |
| removed | Integer | The amount of orphans removed -- They found a parent chart, but were rejected by the converter for being invalid scores, such as having unsupported options or impossible score values. |
Example
Request
N/A
Response
{
"processed": 100,
"failed": 95,
"success": 2,
"removed": 3
}
List your orphaned scores
GET /api/v1/import/orphans
Returns rows from orphan_score for the authenticated user (scores that failed with SongOrChartNotFound and were persisted for later matching). Newest rows are returned first.
Permissions
- submit_score
Query parameters
| Parameter | Type | Description |
| :: | :: | :: |
| limit | Integer (optional) | Page size, 1–100. Default 50. |
| after | String (optional) | Keyset cursor: the rowID from the last orphan in the previous page. Omit on the first request. |
Response
| Property | Type | Description |
| :: | :: | :: |
| orphans | Array | Each object includes orphanID, rowID, importType, gameGroup, timeInserted (ms), message (nullable), summary (nullable, best-effort hint from stored data). |
| hasMore | Boolean | Whether another page exists after this one. |
Get one orphaned score (full payload)
GET /api/v1/import/orphans/:orphanID
Returns a single orphan_score row for the authenticated user, including raw data and context JSON (for debugging unmatched imports). 404 if the row does not exist or belongs to another user.
Permissions
- submit_score
Parameters
| Parameter | Type | Description |
| :: | :: | :: |
| orphanID | Path | The orphan’s orphanID (same as in GET /import/orphans or import errors). |
Response
| Property | Type | Description |
| :: | :: | :: |
| orphanID | String | Stable orphan identifier. |
| importType | String | Import type that produced the orphan. |
| gameGroup | String | Game group. |
| timeInserted | Number | Unix time in ms when the row was stored. |
| message | String or null | Stored error / context message. |
| data | Object | Raw import datapoint (shape depends on importType). |
| context | Object | Raw import context. |
Delete one orphaned score
DELETE /api/v1/import/orphans/:orphanID
Removes a single orphan_score row only if it belongs to the authenticated user. Use this when you no longer want Tachi to keep or retry a given orphan (for example after a bad import).
Permissions
- submit_score
Parameters
| Parameter | Type | Description |
| :: | :: | :: |
| orphanID | Path | The orphan’s orphanID (for example from an import error or from GET /import/orphans). |
Response
Empty body on success (success: true). 404 if no such orphan exists for this user.