Auth

Authentication

Refresh Access Token

post

Refreshes the access token by the refresh token.

Body
refreshTokenstringRequiredExample: eyJhbGciOiJIUzI...Qedy-rosPJLzs3jArh6Vc
Responses
200
Ok
application/json
post
POST //auth/v1/refresh HTTP/1.1
Host: api.dev.hyphen.at
Content-Type: application/json
Accept: */*
Content-Length: 58

{
  "refreshToken": "eyJhbGciOiJIUzI...Qedy-rosPJLzs3jArh6Vc"
}
200

Ok

{
  "credentials": {
    "accessToken": "eyJhbGciOiJIUzI...Qedy-rosPJLzs3jArh6Vc",
    "refreshToken": "eyJhbGciOiJIUzI...Qedy-rosPJLzs3jArh6Vc"
  }
}

Sign Up

Create Account

post

Creates new account and register the current device's key as the initial user key. This involves deploying the account on the chain you've specified.

Body
methodstring · enumRequired

The login channel the user is currently signing in/up.

Example: firebasePossible values:
tokenstringRequired

The access token / ID token / redirect code retrieved as a result of OAuth 2.0 Sign In. Server uses it to call the OAuth provider to verify that the client correctly finished OAuth flow, and fetches users' basic profile information such as email.

Its value differs by channel:

  • For apple, it's the ID token returned after finishing the SIWA process from the client.
  • For firebase, it's the redirect code from OAuth2 Redirect URI.
Example: eyJhbGciOiJIUzI...Qedy-rosPJLzs3jArh6Vc
chainNamestring · enumRequiredPossible values:
userKeyany ofRequired

The user key (usually device key / PassKey) created from the client SDK. Used as one of initial multi-sig keys for creating an account.

or
or
Responses
201Success
application/json
post
POST //auth/v1/signup HTTP/1.1
Host: api.dev.hyphen.at
Content-Type: application/json
Accept: */*
Content-Length: 429

{
  "method": "firebase",
  "token": "eyJhbGciOiJIUzI...Qedy-rosPJLzs3jArh6Vc",
  "chainName": "flow-mainnet",
  "userKey": {
    "type": "device",
    "publicKey": "text",
    "device": {
      "publicKey": "faceb00ccafebabedeadbeefbadf00defaceb00ccafebabedeadbeefbadf00de",
      "pushToken": "bk3RNwTe3H0:CI2k_HHwgIpoDKCIZvvDMExUdFQ3P1...",
      "name": "iPhone 14",
      "osName": "iOS",
      "osVersion": "16.2",
      "deviceManufacturer": "Apple",
      "deviceModel": "SM-265N",
      "lang": "en",
      "type": "mobile"
    }
  }
}
201Success
{
  "account": {
    "id": "text",
    "addresses": [
      {
        "address": "0xAb5801a7D398351b8bE11C439e05C5B3259aeC9B",
        "profileImageUrl": "text",
        "domainName": "vitalik.eth",
        "chainName": "flow-mainnet",
        "chainId": 80001,
        "chainType": "evm"
      }
    ],
    "parent": [
      {
        "address": "0xAb5801a7D398351b8bE11C439e05C5B3259aeC9B",
        "profileImageUrl": "text",
        "domainName": "vitalik.eth",
        "chainName": "flow-mainnet",
        "chainId": 80001,
        "chainType": "evm"
      }
    ],
    "createdAt": "2025-06-24T20:21:07.094Z",
    "updatedAt": "2025-06-24T20:21:07.094Z"
  },
  "transaction": {
    "id": "text",
    "chainName": "flow-mainnet",
    "refUrl": "text"
  },
  "credentials": {
    "accessToken": "eyJhbGciOiJIUzI...Qedy-rosPJLzs3jArh6Vc",
    "refreshToken": "eyJhbGciOiJIUzI...Qedy-rosPJLzs3jArh6Vc"
  }
}

Sign In (with 2FA)

Sign In with 2FA

post

Sign in with two-factor authentication from other device. This is required when the user is trying to sign on the new device.

Body
Responses
200
Ok
application/json
post
POST //auth/v1/signin/2fa HTTP/1.1
Host: api.dev.hyphen.at
Content-Type: application/json
Accept: */*
Content-Length: 441

{
  "request": {
    "method": "firebase",
    "token": "eyJhbGciOiJIUzI...Qedy-rosPJLzs3jArh6Vc",
    "chainName": "flow-mainnet"
  },
  "userKey": {
    "type": "device",
    "publicKey": "text",
    "device": {
      "publicKey": "faceb00ccafebabedeadbeefbadf00defaceb00ccafebabedeadbeefbadf00de",
      "pushToken": "bk3RNwTe3H0:CI2k_HHwgIpoDKCIZvvDMExUdFQ3P1...",
      "name": "iPhone 14",
      "osName": "iOS",
      "osVersion": "16.2",
      "deviceManufacturer": "Apple",
      "deviceModel": "SM-265N",
      "lang": "en",
      "type": "mobile"
    }
  }
}
200

Ok

{
  "twoFactorAuth": {
    "id": "text",
    "accountId": "text",
    "request": {
      "id": "faceb00c-cafe-babe-badd-deadbeef1234",
      "app": {
        "appId": "swirl-dev",
        "appName": "Swirl"
      },
      "userOpInfo": {
        "type": "sign-in",
        "signIn": {
          "email": "[email protected]",
          "ip": "127.0.0.1",
          "location": "Seoul, KR"
        }
      },
      "srcDevice": {
        "id": "deadbeef-dead-beef-cafe-deadbeefcafe",
        "publicKey": "faceb00ccafebabedeadbeefbadf00defaceb00ccafebabedeadbeefbadf00de",
        "sdkVersion": "1.0.0",
        "pushToken": "bk3RNwTe3H0:CI2k_HHwgIpoDKCIZvvDMExUdFQ3P1...",
        "name": "iPhone 14",
        "osName": "iOS",
        "osVersion": "16.2",
        "deviceManufacturer": "Apple",
        "deviceModel": "SM-265N",
        "lang": "en",
        "type": "mobile"
      },
      "destDevice": {
        "id": "deadbeef-dead-beef-cafe-deadbeefcafe",
        "publicKey": "faceb00ccafebabedeadbeefbadf00defaceb00ccafebabedeadbeefbadf00de",
        "sdkVersion": "1.0.0",
        "pushToken": "bk3RNwTe3H0:CI2k_HHwgIpoDKCIZvvDMExUdFQ3P1...",
        "name": "iPhone 14",
        "osName": "iOS",
        "osVersion": "16.2",
        "deviceManufacturer": "Apple",
        "deviceModel": "SM-265N",
        "lang": "en",
        "type": "mobile"
      },
      "message": "deadbeefdeadbeefdeadbeef",
      "requestedAt": "2021-01-01T00:00:00Z"
    },
    "status": "pending",
    "extra": null,
    "result": {
      "txId": "text"
    },
    "expiresAt": "2021-01-01T00:00:00Z"
  },
  "ephemeralAccessToken": "eyJhbGciOiJIUzI...Qedy-rosPJLzs3jArh6Vc"
}

Finish Sign In with 2FA

post

Finish sign in after the user authorized the request on the other device. This API will return the API credentials and account information.

Authorizations
Body
twoFactorAuthRequestIdstringRequired

The latest 2FA request ID.

Example: deadbeef-dead-beef-dead-beefdeadbeef
Responses
200
Ok
application/json
post
POST //auth/v1/signin/2fa/finish HTTP/1.1
Host: api.dev.hyphen.at
Authorization: Bearer JWT
Content-Type: application/json
Accept: */*
Content-Length: 65

{
  "twoFactorAuthRequestId": "deadbeef-dead-beef-dead-beefdeadbeef"
}
200

Ok

{
  "account": {
    "id": "text",
    "addresses": [
      {
        "address": "0xAb5801a7D398351b8bE11C439e05C5B3259aeC9B",
        "profileImageUrl": "text",
        "domainName": "vitalik.eth",
        "chainName": "flow-mainnet",
        "chainId": 80001,
        "chainType": "evm"
      }
    ],
    "parent": [
      {
        "address": "0xAb5801a7D398351b8bE11C439e05C5B3259aeC9B",
        "profileImageUrl": "text",
        "domainName": "vitalik.eth",
        "chainName": "flow-mainnet",
        "chainId": 80001,
        "chainType": "evm"
      }
    ],
    "createdAt": "2025-06-24T20:21:07.094Z",
    "updatedAt": "2025-06-24T20:21:07.094Z"
  },
  "transaction": {
    "id": "text",
    "chainName": "flow-mainnet",
    "refUrl": "text"
  },
  "credentials": {
    "accessToken": "eyJhbGciOiJIUzI...Qedy-rosPJLzs3jArh6Vc",
    "refreshToken": "eyJhbGciOiJIUzI...Qedy-rosPJLzs3jArh6Vc"
  }
}

Sign In (with Challenge)

Starts SignIn Challenge

post

Starts SignIn Challenge. This is required when the user is trying to sign in from the device already registered. The client should request with the public key of the device. If it's not registered, it will raise HTTP 400 with PleaseRegisterKey error.

Issues a random 32-byte challengeData to the client. The client should respond by signing the data with the device's key, within 5 minutes.

The challenge type should be specified with either passKey or deviceKey.

Body
challengeTypestring · enumRequiredPossible values:
publicKeystringRequired

The public key of the PassKey in client-side. Should be 64-byte hex string concatenated with [x: 32byte, y: 32byte].

Responses
200
Ok
application/json
post
POST //auth/v1/signin/challenge HTTP/1.1
Host: api.dev.hyphen.at
Content-Type: application/json
Accept: */*
Content-Length: 199

{
  "challengeType": "deviceKey",
  "request": {
    "method": "firebase",
    "token": "eyJhbGciOiJIUzI...Qedy-rosPJLzs3jArh6Vc",
    "chainName": "flow-mainnet"
  },
  "publicKey": "text",
  "passKey": {
    "username": "[email protected]"
  }
}
200

Ok

{
  "challengeData": "deadbeefdeadbeefdeadbeefdeadbeef",
  "expiresAt": "2023-08-01T00:00:00.000Z"
}

Finish SignIn Challenge

post

Finishes sign in challenge. The client should provide the signature of the challengeData issued by the server. If valid, it will return the API credentials and account information.

Body
challengeTypestring · enumRequiredPossible values:
challengeDatastringRequired
Responses
200
Ok
application/json
post
POST //auth/v1/signin/challenge/respond HTTP/1.1
Host: api.dev.hyphen.at
Content-Type: application/json
Accept: */*
Content-Length: 227

{
  "challengeType": "deviceKey",
  "challengeData": "text",
  "deviceKey": {
    "signature": "text"
  },
  "passKey": {
    "clientDataJSON": "text",
    "authenticatorData": "h4tyVoWj/Tc2Lzxtu79kl9kYtTtraUYwBbIV1ymJaugdAAAAAA==",
    "signature": "MEUCI...p33Sz9c="
  }
}
200

Ok

{
  "account": {
    "id": "text",
    "addresses": [
      {
        "address": "0xAb5801a7D398351b8bE11C439e05C5B3259aeC9B",
        "profileImageUrl": "text",
        "domainName": "vitalik.eth",
        "chainName": "flow-mainnet",
        "chainId": 80001,
        "chainType": "evm"
      }
    ],
    "parent": [
      {
        "address": "0xAb5801a7D398351b8bE11C439e05C5B3259aeC9B",
        "profileImageUrl": "text",
        "domainName": "vitalik.eth",
        "chainName": "flow-mainnet",
        "chainId": 80001,
        "chainType": "evm"
      }
    ],
    "createdAt": "2025-06-24T20:21:07.094Z",
    "updatedAt": "2025-06-24T20:21:07.094Z"
  },
  "transaction": {
    "id": "text",
    "chainName": "flow-mainnet",
    "refUrl": "text"
  },
  "credentials": {
    "accessToken": "eyJhbGciOiJIUzI...Qedy-rosPJLzs3jArh6Vc",
    "refreshToken": "eyJhbGciOiJIUzI...Qedy-rosPJLzs3jArh6Vc"
  }
}

Recover Account

post

Request to recover the account.

Responses
204
No content
post
POST //auth/v1/recover HTTP/1.1
Host: api.dev.hyphen.at
Accept: */*
204

No content

No content

Last updated

Was this helpful?