Here is the full documentaition of the REST API.
All the endpoints in /apiprefix return data in JWT format. The JWTs are signed using the JWKS specified by the property sign_key in the hutch.config file. The key used to sign every response is the one specified in the user profile or the first key if none is specified.
The response format specified in this document is in JSON to make this document easier to read, but you must assume all responses are in JWT format.
Example of JWT response:
HTTP/1.1 200 OK
Content-Type: application/jwt
Pragma: no-cache
Cache-Control: no-store
eyJpYXQiOjE2MzY2Nzk0MDIsImV4cCI6MTYzNjY4MDAwMiwidHlwIjoiSldUIiwiYWxnIjoiUlMyNTYiLCJraWQiOiJyc2EifQ.eyJrZXlzIjpbeyJraWQiOiJyc2EiLC[...]PY2lGWTFjVFQwIn1dfQ.Ewrzjss88[...]R-afaT3A
A JWT response will contain the header values iat and exp which should be verified by the client to mitigate replay attacks.
The API prefix is /api by default, so this value will be used in this document, you can change this in the hutch.config file.
Authentication is required for all endpoints in the /api prefix, those endpoints rely on a valid bearer access token using the JSON Web Token (JWT) Profile for OAuth 2.0 Access Tokens standards, with a valid signature. For all requests, the user identifier used is the sub claim in the access token.
The configuration endpoints /.well-known/hutch-configuration and /jwks don't need authentication.
The configuration endpoints /.well-known/hutch-configuration and /jwks are the only one which send response in JSON format by default.
If the client adds the header Accept: application/jwt in the request, the response will be in JWT format using the first key of the signing JWKS.
/.well-known/hutch-configuration/
GET
Code 200
Content
{
"jwks_uri": URL to the Hutch server JWKS, mandatory
"oidc_server_remote_config": URL to the openid-configuration, optional
"profile_endpoint": URL to the profile API, mandatory
"safe_endpoint": URL to the safe API, mandatory
"scope": List of scopes required by Hutch separated by spaces, mandatory
}This endpoint return a JWKS containing the public keys required to verify the JWTs signatures.
/jwks
GET
Code 200
Content
// Example of JWKS output
{
"keys": [
{
"alg": "RS256",
"e": "AQAB",
"kid": "rsa",
"kty": "RSA",
"n": "zHpJ7[...]TRaxUQ"
},
{
"alg": "ES256",
"crv": "P-256",
"kid": "ecdsa",
"kty": "EC",
"x": "MPx0yi[...]yZH1tY",
"y": "N29F26[...]Y1cTT0"
}
]
}/api/profile/
GET
Code 200
Content
{
"last_updated": Epoch time when the profile was last updated, integer
"message": Profile fortune message, string
"name": Profile user name, string
"picture": Profile picture, string
"sign_kid": kid of the key used to signe responses, string
}Code 404
No profile set for this user
/profile
PUT
{
"name" : string, max 256 characters
"fortune" : string, max 512 characters
"picture" : string, max 16MB characters (mediumblob)
"sign_kid": string, must match an existing kid in the server JWKS
}Code 200
Code 400
Error input parameters
Content: json array containing all errors
/profile
DELETE
Code 200
/safe/
GET
Code 200
Content
[ // Array of safe
{
"name" : string, 128 characters max
"display_name" : string, 512 characters max
"enc_type" : string
"alg_type" : string
}
]Code 403
Profile not set
/safe/@safe_name
GET
Required
@safe_name: Safe name
Code 200
Content
{
"name" : string, 128 characters max
"display_name" : string, 512 characters max
"enc_type" : string, 128 characters max
"alg_type" : string, 128 characters max
}Code 403
Profile not set
OR
Code 404
Safe not found
/safe/
POST
{
"name" : string, 128 characters max, must be unique for the current user
"display_name" : string, 512 characters max
"enc_type" : string, 128 characters max
"alg_type" : string, 128 characters max
}Code 200
Code 403
Profile not set
OR
Code 400
Error input parameters
Content: json array containing all errors
/safe/@safe_name
PUT
Required
@safe_name: Safe name
{
"display_name" : string, 512 characters max
"enc_type" : string, 128 characters max
"alg_type" : string, 128 characters max
}Code 200
Code 403
Profile not set
OR
Code 400
Error input parameters
Content: json array containing all errors
OR
Code 404
Safe not found
/safe/@safe_name
DELETE
Required
@safe_name: Safe name
Code 200
Code 403
Profile not set
OR
Code 404
Safe not found
/safe/@safe_name/key/
GET
Required
@safe_name: Safe name
Code 200
Content
[ // Array of safe keys
{
"type" : string, 128 characters max
"name" : string, 128 characters max
"display_name" : string, 512 characters max
"data" : string, 16M characters max
}
]Code 403
Profile not set
/safe/@safe_name/key/@key/
GET
Required
@safe_name: Safe name
@key : safe key name
Code 200
Content
{
"type" : string, 128 characters max
"name" : string, 128 characters max
"display_name" : string, 512 characters max
"data" : string, 16M characters max
}Code 403
Profile not set
OR
Code 404
Safe key not found
/safe/@safe_name/key/
POST
Required
@safe_name: Safe name
{
"type" : string, 128 characters max
"name" : string, 128 characters max
"display_name" : string, 512 characters max
"data" : string, 16M characters max
}Code 200
Code 403
Profile not set
OR
Code 400
Error input parameters
Content: json array containing all errors
/safe/@name/key/@key
PUT
Required
@safe_name: Safe name
@key : Safe key name
{
"type" : string, 128 characters max
"display_name" : string, 512 characters max
"data" : string, 16M characters max
}Code 200
Code 403
Profile not set
OR
Code 400
Error input parameters
Content: json array containing all errors
OR
Code 404
Safe key not found
/safe/@safe_name/key/@key
DELETE
Required
@safe_name: Safe name
@key : Safe key name
Code 200
Code 403
Profile not set
OR
Code 404
Safe key not found
/safe/@safe_name/coin
GET
Required
@safe_name: Safe name
Code 200
Content
[ // Array of coins
{
"name":string, 128 characters max
"data":string, 16MB max
}
]Code 500
Internal Error
/safe/@safe_name/coin/@coin_name
GET
Required
@safe_name: Safe name
@coin_name: Coin name
Code 200 Content
{
"name":string, 128 characters max
"data":string, 16MB max
}Code 500
Internal Error
OR
Code 404
Coin not found
/safe/@safe_name/coin
POST
Required
@safe_name: Safe name
{
"name":string, 128 characters max, must be unique for the current safe
"data":string, 16MB max
}Code 200
Code 500
Internal Error
OR
Code 400
Error input parameters
Content: json array containing all errors
/safe/@safe_name/coin/@coin_name
PUT
Required
@safe_name: Safe name
@coin_name: Coin name
{
"data":string, 16MB max
}Code 200
Code 500
Internal Error
OR
Code 400
Error input parameters
Content: json array containing all errors
OR
Code 404
Coin not found
/safe/@safe_name/coin/@coin_name
DELETE
Required
@safe_name: Safe name
@coin_name: Coin name
Code 200
Code 500
Internal Error
OR
Code 404
Coin not found