Transaction Modes

Transaction Modes

Every write endpoint on the API takes a mode field with one of two values:

ModeWho signsWho broadcastsWhen to use
unsigned (default)The clientThe client (via POST /v2/transactions)User-facing actions; you control the keypair
signedThe server (Privy platform wallet)The serverTreasury / admin actions where the platform wallet is the authority

Server-signed mode is gated by API-key scopes — for example, fees:claim is required to use mode=signed on the fee-claim endpoints. User-owned operations (airdrop claim, NFT stake/mint, gold lock) reject mode=signed because only the user wallet has authority to sign them.

unsigned flow

Unsigned transaction flow

Response body:

{
  "data": {
    "mode": "unsigned",
    "transaction": "AQABAo...",
    "required_signers": ["..."]
  },
  "meta": { "request_id": "req_…" }
}

transaction is a base64 VersionedTransaction. If the endpoint generated ephemeral keypairs (e.g. POST /v2/tokens returns a mint_secret_key), they appear under required_signers — co-sign with both your wallet and any ephemeral key before submitting.

signed flow

Signed transaction flow

Response body:

{
  "data": {
    "mode": "signed",
    "signature": "5kJ2…"
  },
  "meta": { "request_id": "req_…" }
}

The signature has already been confirmed at confirmed commitment by the time you receive the response.

Which endpoints support which modes

EndpointunsignedsignedRequired scope (signed)
POST /v2/pools/{address}/fee-claims (any kind)fees:claim
POST /v2/airdropsairdrop:admin
POST /v2/airdrops/{id}/claimsn/a — claimer wallet must sign
POST /v2/stakesn/a — user wallet must sign
DELETE /v2/stakes/{asset}n/a
POST /v2/nftsn/a
DELETE /v2/nfts/{asset}n/a
POST /v2/gold-locksn/a
DELETE /v2/gold-locks/{user}n/a
POST /v2/tokensn/a
DELETE /v2/tokens/{mint}/authorities/{type}n/a

Submitting an unsigned transaction

Once your client has signed the transaction, hand it to the API for broadcast via the unified transactions resource:

curl -X POST https://api.piratecrew.fun/v2/transactions \
  -H "Authorization: Bearer $PIRATE_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "transaction": "<base64 signed tx>", "skip_preflight": false }'

For multi-tx atomicity (e.g. a pool create + first buy), set bundle: true and pass an array of signed transactions:

curl -X POST https://api.piratecrew.fun/v2/transactions \
  -H "Authorization: Bearer $PIRATE_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "bundle": true, "signed_transactions": ["<tx1>", "<tx2>"] }'

Simulating before submitting

See Simulating Transactions.

Polling status

curl https://api.piratecrew.fun/v2/transactions/$SIGNATURE \
  -H "Authorization: Bearer $PIRATE_API_KEY"
{
  "data": {
    "signature": "...",
    "status": "confirmed",
    "confirmation_status": "confirmed",
    "err": null,
    "slot": 271234567,
    "confirmations": 12
  },
  "meta": { "request_id": "req_…" }
}

status is the six-value lifecycle enum (unknown | submitted | processing | confirmed | finalized | failed) that most clients should branch on. The raw Solana confirmation_status is preserved for callers that need it. See Transaction Lifecycle for the full state machine and recommended polling pattern.