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

# Send Transaction

> Send a single transaction to the Solana network

Submit a signed transaction to be processed on the Solana network.

## headers

<ParamField header="X-API-Key" type="string" required>
  The API key created from [Altude](https://altude.so)
</ParamField>

## Request Body

<ParamField body="signedTransaction" type="string" required>
  The base64-encoded signed transaction to send
</ParamField>

For a step-by-step example that builds and partially signs a transaction to send SPL tokens—including creating the ATA if missing, setting any required authorities, partial local signing, and submission to Altude's signing endpoint—see the Send example: [Send example](/api-reference/altude-api/transaction/send#example). This Send example is provided as an example only.

## Response

<ResponseField name="success" type="boolean">
  Indicates if the transaction was sent successfully
</ResponseField>

<ResponseField name="signature" type="string">
  The transaction signature
</ResponseField>

<ResponseExample>
  ```json Response theme={null}
  {
    "status": "Queued",
    "message": "Transaction sent successfully",
    "signature": "5eykt4UsFv8P8NJdTREpY1vzqKqZKvdpKuc147dw2N9d"   
  }
  ```
</ResponseExample>

<h2 id="example">
  Example
</h2>

This example demonstrates how to build a Solana transaction that transfers SPL tokens for a given mint and sets the associated token account (ATA) owner (the `authority`) to a specified public key. The fee payer covers account creation and transaction fees. The sample walks through building the transaction, partially signing it locally, and submitting the partially-signed transaction to the Altude signing endpoint for final submission.

<Tabs>
  <Tab title="TypeScript">
    #### Install library

    ```ts theme={null}
      npm install @solana/web3.js @solana/spl-token
    ```

    #### Copy and paste this to your project

    ```ts theme={null}
    import { Connection, Keypair, PublicKey, Transaction } from '@solana/web3.js';
    import { getAssociatedTokenAddress, createAssociatedTokenAccountInstruction, createSetAuthorityInstruction, AuthorityType, TOKEN_PROGRAM_ID, getAccount, createTransferInstruction } from '@solana/spl-token';


     const sourceSignerSecretKey: any[] = [/* your fee payer secret key array here */];
     const API_KEY = 'your-api-key-here';
     // --- Helper functions (inline for docs-only usage) ---
     // Compact helpers used only for this example: connection factory,
     // idempotent ATA creator, serialization helpers, and a signing POST helper.
     function getConnection(rpcUrl: string, commitment: any = 'confirmed') {
       return new Connection(rpcUrl, commitment);
     }

     async function ensureCreateAtaInstruction(connection: Connection, feePayer: PublicKey, mint: PublicKey, owner: PublicKey) {
       // Compute the associated token account (ATA) for the owner + mint.
       const ata = await getAssociatedTokenAddress(mint, owner);

       // If the ATA does not exist on-chain, return an instruction to create it.
       // Caller should add the returned `ix` to the transaction to make creation idempotent.
       const info = await connection.getAccountInfo(ata);
       if (!info) {
         const ix = createAssociatedTokenAccountInstruction(feePayer, ata, owner, mint);
         return { ata, ix };
       }
       return { ata, ix: null };
     }

     function uint8ArrayToBase64(bytes: Uint8Array) {
       // Convert a Uint8Array into a base64 string for JSON transport.
       let binary = '';
       const chunkSize = 0x8000;
       for (let i = 0; i < bytes.length; i += chunkSize) {
         const chunk = bytes.subarray(i, i + chunkSize);
         binary += String.fromCharCode(...chunk);
       }
       return btoa(binary);
     }

     function serializePartialSigned(tx: Transaction, feePayerSecret: number[]) {
       // Partially sign the transaction with the local fee payer key.
       // Use `requireAllSignatures: false` so a remote signer can complete signatures.
       const keypair = Keypair.fromSecretKey(Uint8Array.from(feePayerSecret));
       tx.partialSign(keypair);
       const raw = tx.serialize({ requireAllSignatures: false });
       return uint8ArrayToBase64(raw);
     }

     async function postToSigningServer(url: string, signedBase64: string, apiKey?: string) {
       // POST the partially-signed transaction to Altude. The server is expected
       // to append remaining signatures (if any) and broadcast the transaction.
       const headers: Record<string, string> = { 'Content-Type': 'application/json' };
       if (apiKey) headers['X-API-Key'] = apiKey;
       const res = await fetch(url, { method: 'POST', headers, body: JSON.stringify({ SignedTransaction: signedBase64 }) });
       return res.json();
     }

     // STEP 1 — Build transaction Transfer (idempotent create + set close authority)
     export async function buildTransferTx(mint: string, source: string, destination: string, amount: number , configUrl = 'https://api.altude.so/api/transaction/config') {
       // Load network config (RPC URL and FeePayer public key) from Altude.
       const cfg = await (await fetch(configUrl)).json();
       const connection = getConnection(cfg.RpcUrl);
       const feePayerPub = new PublicKey(cfg.FeePayer);
       const sourcePub = new PublicKey(source);
       const destinationPub = new PublicKey(destination);
       const mintPub = new PublicKey(mint);

       // Prepare an idempotent create-if-missing instruction for the ATA.
       // `ix` will be non-null when the ATA must be created.
       const { ata, ix } = await ensureCreateAtaInstruction(connection, feePayerPub, mintPub, sourcePub);

       const tx = new Transaction();
       tx.feePayer = feePayerPub;

       // Try to fetch ATA account info; absence indicates we should add the create instruction.
       const ataAccount = await getAccount(connection, ata);

       if (ataAccount == null) {
         // Add the ATA creation instruction when needed so the transaction is safe to re-run.
         if (ix) tx.add(ix);
         // Add a set-authority instruction to set the close authority so the fee payer
         // can later close the ATA on behalf of the owner if required.
         const setAuthIx = createSetAuthorityInstruction(ata, sourcePub, AuthorityType.CloseAccount, feePayerPub, [], TOKEN_PROGRAM_ID);
         tx.add(setAuthIx);
       }

       // Add the SPL token transfer instruction to move tokens from source to destination.
       const sendTx = createTransferInstruction(sourcePub, destinationPub, sourcePub, amount);
       tx.add(sendTx);

       // Attach a recent blockhash and return the constructed transaction along with cfg and ata for callers.
       tx.recentBlockhash = (await connection.getLatestBlockhash('finalized')).blockhash;
       return { tx, cfg, ata };
     }

     // STEP 2 — Sign (partial) and submit to signing server
     // Partially sign locally so the signing server can complete signatures and broadcast.
     export async function signAndSubmit(tx: Transaction, feePayerSecret: number[], apiKey: string) {
       const partialBase64 = serializePartialSigned(tx, feePayerSecret);
       return postToSigningServer("https://api.altude.so/api/transaction/send", partialBase64, apiKey);
     }
    ```

    #### Implementation

    ```ts theme={null}
    async function createTransferTransaction(mint: string, source: string, destination: string, amount: number) {
      const { tx, cfg } = await buildTransferTx(mint, source, destination, amount);
      return signAndSubmit(tx, sourceSignerSecretKey, API_KEY);
    }

    createTransferTransaction("mintAddress", "sourceAddress", "destinationAddress", 1000).then(res => {
      console.log('Transaction successful:', res);
    })
    ```
  </Tab>
</Tabs>
