# Launch a coin on Solana

> Build, sign and submit a Payday launch from your app.


A terminal or bot can launch a Payday coin for its user. The API runs the same launcher as payday.direct, so the coin gets the same fee settings: the same Payday token burn, the same DEX reimbursement and the same payouts.

Payday builds the transactions. The user's wallet signs them and pays for the launch. Payday never holds the wallet's key.

## Before you start

You need a **launch key**: sign in on [API keys](/developers/api-keys) and make a key with **Allow this key to launch coins** switched on. Keep it on your server.

## 1. Create the launch

```bash
curl -X POST https://payday.direct/api/v1/launches -H "Authorization: Bearer pd_YOUR_KEY" -H "Content-Type: application/json" -d '{
  "wallet": "THE_LAUNCHING_WALLET_ADDRESS",
  "name": "Example Coin",
  "symbol": "Example",
  "description": "What the coin is about.",
  "image": "BASE64_PNG_JPEG_GIF_OR_WEBP",
  "dev_buy_sol": 0.5,
  "fees_to": "examplehandle"
}'
```

The answer has the new coin's `mint`, a launch `id` and the transactions to sign. Nothing is on chain yet. [Every field](/developers/api-reference/launch-on-solana/create-launch).

## 2. Sign, without sending

Have the wallet sign every transaction within about 60 seconds. Each is a base64 Solana versioned transaction; the `launch` one already carries the coin's own signature, so the wallet adds its signature and leaves the message as it is. A wallet's "sign all transactions" does exactly this.

```javascript JavaScript
import { VersionedTransaction } from "@solana/web3.js";
const txs = launch.transactions.map((t) => VersionedTransaction.deserialize(Buffer.from(t.transaction, "base64")));
const signed = await wallet.signAllTransactions(txs);   // Phantom, Solflare, or your own signer
const out = {}; const split = [];
launch.transactions.forEach((t, i) => {
  const b64 = Buffer.from(signed[i].serialize()).toString("base64");
  if (t.name.startsWith("split_")) split.push(b64); else out[t.name] = b64;
});
if (split.length) out.split = split;
```

> Warning: Do not send them yourself. Payday checks they are the ones it built and sends them in the right order. A changed transaction is refused with `not_our_tx`.

## 3. Submit

```bash
curl -X POST https://payday.direct/api/v1/launches/LAUNCH_ID/submit -H "Authorization: Bearer pd_YOUR_KEY" -H "Content-Type: application/json" \
  -d '{ "signed": { "launch": "BASE64", "buy": "BASE64", "split": ["BASE64"] } }'
```

The answer has `status: "launched"`, the `mint`, the launch `signature` and the coin's links.

## The states of a launch

| Status | What it means | What to do |
|---|---|---|
| `awaiting_signature` | Built; nothing on chain | Have the wallet sign every transaction within about 60 seconds, then submit |
| `submitting` | Sent, not confirmed yet (`504 unconfirmed`) | Submit the same launch again or read `GET /launches/{id}`; never create it again |
| `launched` | The coin exists | Done. If `fee_split.status` is `pending`, finish the split below |
| `expired` | Signed too late, or the network ruled it out (`410 expired`, `not_landed`) | Create a new launch |

## When the network is slow

`504 unconfirmed` means the launch was sent and is not confirmed yet. **Never create it again.** Submit the same launch again, or read `GET /launches/{id}`, which stays `submitting` until it turns `launched` or `expired`. `not_landed` means the network ruled it out and no coin was made: create a new launch.

## The fee split

The `split_` transactions lock the coin's fees to the account in `fees_to` in the same signing round. If `fee_split.status` comes back `pending`, the coin stays hidden on Payday until it is locked: ask for fresh transactions with `POST /launches/{id}/split`, have the wallet sign **and send** these itself, then report their signatures to `POST /launches/{id}/split/confirm`.

## Rules

- The launching wallet pays the network fees and its first buy. The DEX reimbursement goes to the wallet that signed the launch.
- Launches made with your key are recorded under the X account that owns the key.
- 8 launches per wallet and 30 per key every 10 minutes, 500 per key a day.
- An account that opted out of Payday cannot be named in `fees_to`.
