API: Difference between revisions
Line 205: | Line 205: | ||
* A single string, in which case the string will be treated as the token text with default launch options. Similar to the [[TapTo API#Launch Endpoint|Launch Endpoint]]. | * A single string, in which case the string will be treated as the token text with default launch options. Similar to the [[TapTo API#Launch Endpoint|Launch Endpoint]]. | ||
* Or | * Or a parameters object with the following keys: | ||
{| class="wikitable" | {| class="wikitable" | ||
Line 220: | Line 220: | ||
|uid | |uid | ||
|string | |string | ||
|No | |No* | ||
|The UID of the token being scanner. For example, the UID of an NFC tag. Used for matching mappings. | |The UID of the token being scanner. For example, the UID of an NFC tag. Used for matching mappings. | ||
|- | |- | ||
|text | |text | ||
|string | |string | ||
|No | |No* | ||
|The main text to be processed from a scan, should contain [[TapScript]]. | |The main text to be processed from a scan, should contain [[TapScript]]. | ||
|- | |- | ||
|data | |data | ||
|string | |string | ||
|No | |No* | ||
|The raw data read from a token, converted to a hexadecimal string. Used in mappings and detection of NFC toys such as Amiibos and Lego Dimensions. | |The raw data read from a token, converted to a hexadecimal string. Used in mappings and detection of NFC toys such as Amiibos and Lego Dimensions. | ||
|} | |} | ||
These parameters allow emulating a token exactly as it would be read directly from an attached reader on the server. A request's parameters must contain at least a populated <code>uid</code>, <code>text</code> or <code>data</code> value. | These parameters allow emulating a token exactly as it would be read directly from an attached reader on the server. A request's parameters must contain at least a populated <code>uid</code>, <code>text</code> or <code>data</code> value. | ||
This method does not have any response results. Currently, it is not reported if the TapScript encounters an error during launching. | This method does not have any response results. Currently, it is not reported if the launched TapScript encounters an error during launching. | ||
==== stop ==== | ==== stop ==== | ||
Line 247: | Line 247: | ||
Query the media database and return all matching indexed media. | Query the media database and return all matching indexed media. | ||
This request accepts the following | This request accepts the following parameters object: | ||
{| class="wikitable" | {| class="wikitable" | ||
!Key | !Key | ||
Line 257: | Line 257: | ||
|string | |string | ||
|Yes | |Yes | ||
| | |Case-insensitive search by filename. By default, query is split by white space and results are found which contain every word. | ||
|- | |- | ||
|system | |system | ||
|string[] | |string[] | ||
|No | |No | ||
| | |Case-sensitive list of system IDs to restrict search to. A missing key or empty list will search all systems. | ||
|- | |- | ||
|maxResults | |maxResults | ||
|number | |number | ||
|No | |No | ||
| | |Max number of results to return. Default is 250. | ||
|} | |||
And a response with the following results object: | |||
{| class="wikitable" | |||
!Key | |||
!Type | |||
!Required | |||
!Description | |||
|- | |||
|results | |||
|Media[] | |||
|Yes | |||
|A list of all search results from the given query. | |||
|- | |||
|total | |||
|number | |||
|Yes | |||
|Total number of search results. | |||
|} | |||
===== Media object ===== | |||
{| class="wikitable" | |||
!Key | |||
!Type | |||
!Required | |||
!Description | |||
|- | |||
|system | |||
|System | |||
|Yes | |||
|System which the media has been indexed under. | |||
|- | |||
|name | |||
|string | |||
|Yes | |||
|A human-readable version of the result's filename without a file extension. | |||
|- | |||
|path | |||
|string | |||
|Yes | |||
|Path to the media file. If possible, this path will be compressed into the <code><system>/<path></code> launch format. | |||
|} | |||
===== System object ===== | |||
{| class="wikitable" | |||
!Key | |||
!Type | |||
!Required | |||
!Description | |||
|- | |||
|id | |||
|string | |||
|Yes | |||
|Internal system ID for this system. | |||
|- | |||
|name | |||
|string | |||
|Yes | |||
|Display name of the system. | |||
|- | |||
|category | |||
|string | |||
|Yes | |||
|Category of system. This field is not yet formalized. | |||
|} | |} | ||
==== media.index ==== | ==== media.index ==== | ||
Start a new media database index. | Start a new media database index. | ||
This method can, optionally, take a list of strings of system IDs to restrict the index to just those systems. | |||
==== systems ==== | ==== systems ==== | ||
Line 320: | Line 385: | ||
==== version ==== | ==== version ==== | ||
Return | Return server's current version and platform. | ||
== Notifications == | == Notifications == | ||
Notifications let a server or client know | Notifications let a server or client know an event has occurred. | ||
=== Reader === | === Reader === | ||
Line 349: | Line 414: | ||
Media has stopped on server. | Media has stopped on server. | ||
==== media. | ==== media.indexing ==== | ||
The state of the indexing process has changed. | The state of the indexing process has changed. |
Revision as of 14:36, 19 September 2024
This page refers to the future version 2.0.0 of TapTo which is in active development. Please don't use any information on this page until it's been finalised and released. |
The TapTo API is an API available on and published by every device running the core TapTo software. This API allows management of all TapTo features which would not present a security risk. The TapTo Life app uses this API for all communication with TapTo devices.
This page documents the protocol used to communicate with the API and each method available to interact with a TapTo device. It is the source of truth when developing applications that interact with TapTo.
Communication Protocol
The API uses a standard WebSocket connection to exchange JSON payloads using a custom variant of the JSON-RPC 2.0 protocol. It is not compatible with standard JSON-RPC libraries.
All remote unsecured WebSocket connections must encrypt every payload using the encryption layer detailed below, or else the payload will be immediately rejected. Local unencrypted connections are allowed, depending on the platform and privilege context of the running service.
Communication follows a loose client-server relationship. Clients, by default, are not expected to implement the API beyond what that particular client needs to function.
Connection
Connections to the API can be established with any standard WebSocket client, using the root endpoint (/
) of the HTTP server published by the TapTo service. By default, the HTTP server is accessible on port 7497
. Keep in mind this port is configurable by the user.
An example address for connecting to the API: ws://10.0.0.123:7497/
The connection requires no special configuration or authentication to begin.
JSON Payloads
Server and clients communicate back and forth using JSON payloads and a request-response based on the JSON-RPC 2.0 protocol. The TapTo protocol is incompatible with existing JSON-RPC libraries.
Because a WebSocket connection is asynchronous, request payloads are tagged with a unique ID. The client must keep track of IDs sent to another client and wait for a matching response object.
Requests
A request object asks the connected server to run a pre-defined method, and report back when it's completed with a response object.
An example request:
{
"tapto": 1,
"id": "9ab7679f-6de9-11ef-9a9b-020304050607",
"timestamp": 1725803556229,
"method": "media.search",
"params": {
"query": "240p"
}
}
This request would query TapTo's media database for a file containing the word "240p" and return a response with the search results.
Request keys:
Key | Type | Required | Description |
---|---|---|---|
tapto | number | Yes | Specifies the protocol version and is used to validate a payload. It must be contained in every request or else the request will be rejected. Currently this must be the integer 1 .
|
id | string | Yes* | A UUID v1 generated by the requesting client, used to match requests back to responses. A request missing this key is valid but would be treated as a notification and not receive any response (or an error). |
timestamp | number | Yes | An integer timestamp of the current UNIX epoch in milliseconds when the request was generated. This value is used by the encryption layer to validate the request. |
method | string | Yes | A string corresponding to a method to be run by the receiving server. |
params | any | No | Arguments supplied for the method. The value of this key depends on the method used and is omitted for some methods. |
All available request methods and their parameters are documented below.
Notifications
Notifications are requests which do not contain an ID. Otherwise, they are identical to a standard request object. Notifications can be sent by either server or client and do not receive a response.
Like standard requests, notifications may or may not have parameters and its value will depend on the method. Types of notifications are documented below.
Responses
Every request sent must have a matching response. An example response to the media.search request shown above:
{
"tapto": 1,
"id": "9ab7679f-6de9-11ef-9a9b-020304050607",
"timestamp": 1725803557,
"result": {
"results": [{
"system": {
"id": "Gameboy",
"name": "Gameboy"
},
"name": "240p Test Suite (PD) v0.03 tepples",
"path": "Gameboy/240p Test Suite (PD) v0.03 tepples.gb"
}],
"total": 1
}
}
Response keys:
Key | Type | Required | Description |
---|---|---|---|
tapto | number | Yes | Same as a request. |
id | string | Yes | Same as a request. The same ID sent by the original request. |
timestamp | number | Yes | Same as a request, with an updated time. |
result | any | No* | Return value of the method. May be null depending on the method. See methods for possible values. |
error | Error | No* | If a method failed, this key will be populated with the error details and the result key will be empty. See below for details about errors. |
Response Errors
If a method fails, it will populate the error key in the response object with details about the failure. An example of a failed request:
{
"tapto": 1,
"id": "9ab7679f-6de9-11ef-9a9b-020304050607",
"timestamp": 1725805903,
"error": {
"code": 1,
"message": "query or system is required"
}
}
Error keys:
Key | Type | Required | Description |
---|---|---|---|
code | number | Yes | An integer specifying the general error category. |
message | string | Yes | Short human readable message explaining the error cause if possible. |
Error codes are not finalised yet. |
Protocol Errors
If a low-level error occurs before a request context can be established, a protocol error will be sent back. This can happen, for example, if a JSON payload is malformed or a payload could not be decrypted. They're identical to an error response except they will have no ID.
Protocol errors may be sent unencrypted if a secure context couldn't be established.
Encryption Layer
The API supports an encryption layer when communicating via an insecure WebSocket connection. This layer is required for all insecure remote connections, and payloads will be rejected if not encrypted.
Encryption is performed using AES256 and a shared secret key held by both server and client which is exchanged outside the API. Each payload sent must be encrypted by the sender and decrypted by the receiver. Responses must also be encrypted.
Be aware that although this process authenticates a client, TapTo does not currently enforce any type of role-based access. Any client with a valid secret key must be trusted with full access to the API.
An encrypted payload is in the format: tapto:<client id>:<base64 encoded data>
The client ID is matched back to the TapTo service's internal database of IDs and associated secret keys. If there's a match, it will attempt to decrypt the encrypted data.
Clients are also managed through the API, but can only be done so via a device-local connection. Each client must have accurate time set, as the timestamp is validated on the receiving server and checked against a history of payloads.
If a payload is decrypted successfully, it continues through the standard protocol process until the response which will be encrypted before sending back.
Anonymous Access
Anonymous unencrypted access is, generally, allowed when an API connection is made from a loopback address (i.e. from the same device TapTo is running). This access depends on the platform and whether the service is running with elevated privileges. Check the page for the specific platform to make sure it's available to you.
This access is also allowed when a connection is made over a WebSocket Secure (wss) connection.
Launch Endpoint
The HTTP server has one other endpoint which allows restricted access to trigger generic launch methods using a GET request. This endpoint is specifically meant to support uses such as QR codes scanned by a phone.
The endpoint is: /l/
An example request: GET http://10.0.0.123:7497/l/**launch.system:snes
This would act as though a token with the text **launch.system:snes
had been scanned, depending on this text being explicitly allowed in the config file.
Methods
Methods are used to execute actions and request data back from the API.
Launching
launch
Emulate the scanning of a token.
This method accepts two types of parameters:
- A single string, in which case the string will be treated as the token text with default launch options. Similar to the Launch Endpoint.
- Or a parameters object with the following keys:
Key | Type | Required | Description |
---|---|---|---|
type | string | No | An internal category of the type of token being scanned. Not currently in use outside of logging. |
uid | string | No* | The UID of the token being scanner. For example, the UID of an NFC tag. Used for matching mappings. |
text | string | No* | The main text to be processed from a scan, should contain TapScript. |
data | string | No* | The raw data read from a token, converted to a hexadecimal string. Used in mappings and detection of NFC toys such as Amiibos and Lego Dimensions. |
These parameters allow emulating a token exactly as it would be read directly from an attached reader on the server. A request's parameters must contain at least a populated uid
, text
or data
value.
This method does not have any response results. Currently, it is not reported if the launched TapScript encounters an error during launching.
stop
Kill any active launcher, if possible.
This methods takes no parameters and does not currently report whether it was successful or not.
Media
media.search
Query the media database and return all matching indexed media.
This request accepts the following parameters object:
Key | Type | Required | Description |
---|---|---|---|
query | string | Yes | Case-insensitive search by filename. By default, query is split by white space and results are found which contain every word. |
system | string[] | No | Case-sensitive list of system IDs to restrict search to. A missing key or empty list will search all systems. |
maxResults | number | No | Max number of results to return. Default is 250. |
And a response with the following results object:
Key | Type | Required | Description |
---|---|---|---|
results | Media[] | Yes | A list of all search results from the given query. |
total | number | Yes | Total number of search results. |
Media object
Key | Type | Required | Description |
---|---|---|---|
system | System | Yes | System which the media has been indexed under. |
name | string | Yes | A human-readable version of the result's filename without a file extension. |
path | string | Yes | Path to the media file. If possible, this path will be compressed into the <system>/<path> launch format.
|
System object
Key | Type | Required | Description |
---|---|---|---|
id | string | Yes | Internal system ID for this system. |
name | string | Yes | Display name of the system. |
category | string | Yes | Category of system. This field is not yet formalized. |
media.index
Start a new media database index.
This method can, optionally, take a list of strings of system IDs to restrict the index to just those systems.
systems
List all currently indexed systems.
Settings
settings
List all currently configured settings.
settings.update
Permanently update one or more settings.
Mappings
mappings
List all stored mappings.
mappings.new
Create a new mapping.
mappings.delete
Delete an existing mapping.
mappings.update
Change an existing mapping.
Readers
readers
List all currently connected readers.
readers.write
Attempt to write given text to the first available write-capable reader, if possible.
Clients
Clients can only be managed through the API via a device-local connection.
clients
List all clients (including disconnected) and associated data.
clients.new
Create a new client with a newly generated ID and secret.
clients.delete
Delete an existing client.
Service
version
Return server's current version and platform.
Notifications
Notifications let a server or client know an event has occurred.
Reader
readers.connected
A new reader was connected to the server.
readers.disconnected
A connected reader was disconnected from the server.
Tokens
tokens.launching
A new token was added to the launch queue.
tokens.active
The state of the currently active token has changed.
Media
media.started
New media was started on server.
media.stopped
Media has stopped on server.
media.indexing
The state of the indexing process has changed.