> ## Documentation Index
> Fetch the complete documentation index at: https://pay3.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Request a Sign-In Challenge for Your Stellar Wallet

> Generate a one-time sign-in challenge for a Stellar wallet address. Sign the returned message with your wallet, then submit the signature to verify.

The challenge endpoint is the **first step of wallet-based authentication** on Pay3. Send your Stellar public key and receive a one-time, nonce-bound message that you must sign with your wallet's private key using Freighter (or any compatible Ed25519 signer). The signed message is then submitted to [`POST /api/auth/verify`](https://pay3.mintlify.site/api-reference/auth/verify) to complete sign-in and establish a session.

## Endpoint

**`POST /api/auth/challenge`**

No authentication is required to call this endpoint.

***

## Request Body

**walletAddress** `string` *required*

Your Stellar Ed25519 public key, beginning with `G`. Must be a valid Stellar
account address (56-character StrKey-encoded key).

**Example:** `GAHJJJKMOKYE4RVPZEWZTKH5FVI4PA3VL7GK2LFNUBSGBV8XVMHXV6R`

***

## Response

All Pay3 API responses are wrapped in a standard envelope:

```json theme={null}
{
  "data": { ... },
  "requestId": "req_01hx2q3r4s5t6u7v8w9x0y1z"
}
```

A successful `200 OK` response returns a challenge object inside `data`. Pass the `message` field to your wallet signer, then send the resulting signature along with the `nonce` to the verify endpoint.

**data** `object`

The challenge payload.

**data fields**

**data.challengeId** `string`

Unique identifier for this challenge. Returned for informational purposes;
you do not need to include this in your verify request.

**data.nonce** `string`

The randomly-generated nonce embedded in the challenge message. Include
this value in the body of your subsequent `POST /api/auth/verify` request.

**data.message** `string`

The plain-text challenge message that your wallet must sign. Pass this
string directly to `freighter.signMessage()` or an equivalent signer.

The message follows this structure:

```
Pay3 wants you to sign in with your Stellar wallet.

Wallet: <walletAddress>
Network: <testnet|public>
Nonce: <nonce>
Issued At: <ISO 8601 timestamp>
Expiration: <ISO 8601 timestamp>
```

**data.walletAddress** `string`

The normalized Stellar public key echoed back after validation.

**data.network** `string`

The Stellar network this challenge was issued for — either `testnet` or `public`.

**data.expiresAt** `string`

ISO 8601 timestamp indicating when this challenge expires.

**requestId** `string`

A unique identifier for this API request, useful for support and debugging.

> [!NOTE]
>
> Challenges expire **5 minutes** after issuance. If your user takes longer than that to sign, request a fresh challenge. Each new request for the same wallet address automatically invalidates any previously unconsumed challenge for that address.

***

## Example

### Request

```bash theme={null}
curl --request POST \
  --url https://api.pay3.dev/api/auth/challenge \
  --header 'Content-Type: application/json' \
  --data '{
    "walletAddress": "GAHJJJKMOKYE4RVPZEWZTKH5FVI4PA3VL7GK2LFNUBSGBV8XVMHXV6R"
  }'
```

### Response Body

```json theme={null}
{
  "data": {
    "challengeId": "a3f8c2d1-04b5-4e6f-9a7b-8c0d1e2f3a4b",
    "nonce": "8f3a92b1c4e07d56af2190be",
    "message": "Pay3 wants you to sign in with your Stellar wallet.\n\nWallet: GAHJJJKMOKYE4RVPZEWZTKH5FVI4PA3VL7GK2LFNUBSGBV8XVMHXV6R\nNetwork: testnet\nNonce: 8f3a92b1c4e07d56af2190be\nIssued At: 2024-11-01T12:00:00.000Z\nExpiration: 2024-11-01T12:05:00.000Z",
    "walletAddress": "GAHJJJKMOKYE4RVPZEWZTKH5FVI4PA3VL7GK2LFNUBSGBV8XVMHXV6R",
    "network": "testnet",
    "expiresAt": "2024-11-01T12:05:00.000Z"
  },
  "requestId": "req_01hx2q3r4s5t6u7v8w9x0y1z"
}
```

***

## Error Responses

| HTTP Status | Description |
| - | - |
| `400 Bad Request` | `walletAddress` is missing or not a valid Stellar public key. |
| `422 Unprocessable Entity` | Address format is syntactically invalid (not a `G...` key). |


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.