# Validating Cotter's Identity Token

Cotter's token includes the user's email or phone number, your `API_KEY_ID`, and a `signature` . Here's the full `token` object:

```javascript
"token": {
    "identifier_id": "e8a47aff-f520-4b8d-952b-79d36d10fb3e",
    "expire_at": "1588849208",
    "identifier": "+12345678910", // user's email or phone
    "identifier_type": "PHONE",
    "receiver": "<YOUR API KEY ID>",
    "signature": "21P6mXSF2x357kZGkEMQTRTn3r...",
    "timestamp": "1586257208" // unix Timestamp
 }
```

{% hint style="info" %}
Check that the `receiver` contains your `API_KEY_ID`
{% endhint %}

#### Verifying the Signature

The signature ensures that this token comes from Cotter's server:

* Signature algorithm: `ed25519`
* Cotter's Public Key: `qqOaiQGjGsxBMgI5rdAasaACRiJthOqadmefjY5mS/c=`
* Signed Message:

```
{token.identifier}{token.identifier_type}{token.receiver}{token.expire_at}
```

{% hint style="info" %}
Note that there is no space and no `{}` in the message. It's all just 1 long string. ex. `+1234567890PHONEaaf7319d-8f91-4752-a23f-c43ba862d5481582679175`
{% endhint %}

#### Example

{% tabs %}
{% tab title="JavaScript" %}

```javascript

var cotter = require("cotter-token-js");

var cotterIdentity = new cotter.CotterIdentity(token);
var valid = cotterIdentity.validate()
```

{% endtab %}

{% tab title="React Native" %}

```javascript
import { Cotter } from 'react-native-cotter';

var valid = Cotter.validateIdentityResponse(response.token);
```

{% endtab %}

{% tab title="Go" %}

```go
// https://golang.org/pkg/crypto/ed25519/
func Verify(publicKey string, signStr string, args ...string) (bool, error) {
    str := []byte(strings.Join(args, ""))
    fmt.Println(strings.Join(args, ""))
    pubKey, err := base64.StdEncoding.DecodeString(publicKey)
    if err != nil {
        return false, responses.NewError("Fail verifying signature decoding pubkey", err)
    }
    signature, err := base64.StdEncoding.DecodeString(signStr)
    if err != nil {
        return false, responses.NewError("Fail verifying signature decoding signature", err)
    }
    valid := ed25519.Verify(pubKey, str, signature)
    return valid, nil
}

// Usage
valid, err := Verify(enum.CotterPublicKey, token.Signature, token.Identifier, string(token.IdentifierType), token.ReceiverID.String(), token.ExpireAt)

```

{% endtab %}

{% tab title="Python" %}

```python
# https://pynacl.readthedocs.io/en/stable/signing/
import binascii
import nacl.signing
import nacl.encoding

pub64 = "qqOaiQGjGsxBMgI5rdAasaACRiJthOqadmefjY5mS/c="
signatureB64 = token["signature"]
message = token["identifier"] + token["identifier_type"] + token["receiver"] + token["expire_at"]

signb = binascii.a2b_base64(signatureB64)
msgb = str.encode(message)

verify_key = nacl.signing.VerifyKey(pub64, encoder=nacl.encoding.Base64Encoder)
verify_key.verify(msgb, signb)
```

{% endtab %}
{% endtabs %}

Libraries for `ed25519` algorithm are available in [Javascript](https://tweetnacl.js.org/#/), [Golang](https://golang.org/pkg/crypto/ed25519/), [Python](https://pynacl.readthedocs.io/en/stable/signing/) and other languages.


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.cotter.app/older-api/validating-cotters-token.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
