# 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](../../codebase/import/import-types.md). | | `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](../../codebase/import/import-types.md) | !!! 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 | | :: | :: | :: | | `` | 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= ``` #### Response ```js { "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** ```js { 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 | | :: | :: | :: | | `` | 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](../../codebase/import/orphans.md) 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 ```js { "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.