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

# Incorporate a Token

> Complete guide to incorporate a company for a token using the Bags SDK with TypeScript and Node.js

In this guide, you'll learn how to incorporate a company for your token using the Bags TypeScript SDK. The incorporation flow involves creating a payment, submitting incorporation details with founder information, having each founder complete their verification forms, and then starting the incorporation process once all prerequisites are met.

## Prerequisites

Before starting, make sure you have:

* Completed our [TypeScript and Node.js Setup Guide](/how-to-guides/typescript-node-setup).
* Got your API key from the [Bags Developer Portal](https://dev.bags.fm).
* A Solana wallet with SOL or USDC to pay the incorporation fee.
* A launched token mint address.
* Installed the additional dependencies for this guide:
  ```bash theme={null}
  npm install @solana/web3.js bs58
  ```

## 1. Set Up Environment Variables

This guide requires your wallet's private key. Add it to your base `.env` file:

```bash theme={null}
# .env
BAGS_API_KEY=your_api_key_here
SOLANA_RPC_URL=https://api.mainnet-beta.solana.com
PRIVATE_KEY=your_base58_encoded_private_key_here  # Required for this guide
```

<Note>
  You can export your private key from wallets like Bags, Phantom, or Backpack.
</Note>

## 2. The Incorporation Script

Here is the complete script for incorporating a token. Save it as `incorporate-token.ts`.

The incorporation flow is split into three separate functions that you call at different stages:

1. **`createPaymentAndSubmitDetails`** — creates the payment, signs it on-chain, and submits incorporation details. Returns each founder's form URL.
2. **`checkIncorporationStatus`** — checks whether all founders have completed their forms and the project is ready for incorporation.
3. **`startIncorporationProcess`** — triggers the incorporation once all founders have completed their forms.

After submitting details, share each founder's `formUrl` with them so they can complete their verification. Founders may take hours or days to finish, so these functions are designed to be called independently.

## Endpoints Used Under the Hood

This guide uses these API reference operations via the SDK:

* [`POST /incorporate/start-payment`](/api-reference/create-incorporation-payment) via `sdk.incorporation.startPayment()`
* [`POST /incorporate/incorporate`](/api-reference/create-incorporation) via `sdk.incorporation.incorporate()`
* [`POST /incorporate/start-incorporation/:tokenAddress`](/api-reference/start-incorporation) via `sdk.incorporation.startIncorporation()`
* [`GET /incorporate/list`](/api-reference/get-incorporation-list) via `sdk.incorporation.list()`
* [`GET /incorporate/details/:tokenAddress`](/api-reference/get-incorporation-details) via `sdk.incorporation.getDetails()`

```typescript theme={null}
import dotenv from "dotenv";
dotenv.config({ quiet: true });

import { BagsSDK, signAndSendTransaction } from "@bagsfm/bags-sdk";
import { Keypair, Connection, PublicKey } from "@solana/web3.js";
import bs58 from "bs58";

const BAGS_API_KEY = process.env.BAGS_API_KEY;
const SOLANA_RPC_URL = process.env.SOLANA_RPC_URL;
const PRIVATE_KEY = process.env.PRIVATE_KEY;

if (!BAGS_API_KEY || !SOLANA_RPC_URL || !PRIVATE_KEY) {
    throw new Error("BAGS_API_KEY, SOLANA_RPC_URL, and PRIVATE_KEY are required");
}

const connection = new Connection(SOLANA_RPC_URL);
const sdk = new BagsSDK(BAGS_API_KEY, connection, "processed");

async function createPaymentAndSubmitDetails(params: {
    tokenAddress: string;
    projectName: string;
    preferredCompanyNames: [string, string, string];
    incorporationShareBasisPoint: number;
    founders: Array<{
        firstName: string;
        lastName: string;
        email: string;
        nationalityCountry: string;
        taxResidencyCountry: string;
        residentialAddress: string;
        shareBasisPoint: number;
    }>;
    category?: "RWA" | "AI" | "DEFI" | "INFRA" | "DEPIN" | "LEGAL" | "GAMING" | "NFT" | "MEME";
    twitterHandle?: string;
    payWithSol?: boolean;
}) {
    try {
        const keypair = Keypair.fromSecretKey(bs58.decode(PRIVATE_KEY!));
        const commitment = sdk.state.getCommitment();
        const tokenMint = new PublicKey(params.tokenAddress);

        console.log(`🏢 Starting incorporation for token ${params.tokenAddress}`);
        console.log(`👤 Payer wallet: ${keypair.publicKey.toBase58()}`);

        // 1a. Create payment
        console.log("\n📝 Creating incorporation payment...");
        const payment = await sdk.incorporation.startPayment({
            payerWallet: keypair.publicKey,
            payWithSol: params.payWithSol,
        });

        console.log(`💰 Incorporation price: ${payment.priceUSDC} USDC`);
        console.log(`📋 Order UUID: ${payment.orderUUID}`);

        // 1b. Sign and send the payment transaction
        console.log("\n✍️  Signing and sending payment transaction...");
        const paymentSignature = await signAndSendTransaction(
            connection,
            commitment,
            payment.transaction,
            keypair
        );

        console.log(`✅ Payment confirmed: ${paymentSignature}`);

        // 1c. Submit incorporation details
        console.log("\n📋 Submitting incorporation details...");
        const incorporation = await sdk.incorporation.incorporate({
            orderUUID: payment.orderUUID,
            paymentSignature,
            projectName: params.projectName,
            tokenAddress: tokenMint,
            founders: params.founders,
            incorporationShareBasisPoint: params.incorporationShareBasisPoint,
            preferredCompanyNames: params.preferredCompanyNames,
            category: params.category,
            twitterHandle: params.twitterHandle,
        });

        console.log(`✅ Incorporation details submitted!`);
        console.log(`📊 Status: ${incorporation.incorporationStatus}`);

        // 1d. Display founder form URLs
        console.log("\n🔗 Founder form URLs — share these with each founder:");
        console.log("   Each founder must open their URL and complete the required forms.\n");

        for (const founder of incorporation.founders) {
            console.log(`  👤 ${founder.firstName} ${founder.lastName}`);
            if (founder.formUrl) {
                console.log(`     Form URL: ${founder.formUrl}`);
            }
            console.log();
        }

        console.log("⏳ Once all founders have completed their forms, run checkIncorporationStatus() to verify readiness.");
    } catch (error) {
        console.error("🚨 Incorporation setup failed:", error);
        throw error;
    }
}

async function checkIncorporationStatus(tokenAddress: string) {
    try {
        const tokenMint = new PublicKey(tokenAddress);
        const details = await sdk.incorporation.getDetails({ tokenAddress: tokenMint });

        console.log(`\n📊 Incorporation status for ${tokenAddress}`);
        console.log(`   Status: ${details.incorporationStatus}`);
        console.log(`   Ready for incorporation: ${details.isReadyForIncorporation ? "✅ Yes" : "❌ No"}`);

        if (!details.isReadyForIncorporation) {
            console.log("\n   Not all founders have completed their forms yet.");
            console.log("   You can also check individual founder progress with sdk.incorporation.list():");

            const projects = await sdk.incorporation.list();
            const project = projects.find((p) => p.tokenAddress === tokenAddress);

            if (project) {
                for (const founder of project.founders) {
                    const kycDone = founder.kycStatus === "VERIFIED";
                    console.log(`\n   👤 ${founder.firstName} ${founder.lastName}`);
                    console.log(`      KYC: ${kycDone ? "✅" : "❌"} ${founder.kycStatus}`);
                    console.log(`      PEP form: ${founder.pepCompleted ? "✅" : "❌"}`);
                    console.log(`      IP attribution: ${founder.ipAttributionAcknowledged ? "✅" : "❌"}`);
                }
            }
        }

        return details;
    } catch (error) {
        console.error("🚨 Failed to check status:", error);
        throw error;
    }
}

async function startIncorporationProcess(tokenAddress: string) {
    try {
        const tokenMint = new PublicKey(tokenAddress);

        console.log(`\n🚀 Starting incorporation process for ${tokenAddress}...`);
        const result = await sdk.incorporation.startIncorporation({ tokenAddress: tokenMint });

        console.log(`🎉 Incorporation started successfully!`);
        console.log(`🪙 Token: ${result.tokenAddress}`);
        console.log(`✅ Incorporation started: ${result.incorporationStarted}`);

        return result;
    } catch (error) {
        console.error("🚨 Failed to start incorporation:", error);
        throw error;
    }
}

// ──────────────────────────────────────────────
// Usage — run one function at a time
// ──────────────────────────────────────────────

// 1. First, create the payment and submit incorporation details:
createPaymentAndSubmitDetails({
    tokenAddress: "YOUR_TOKEN_MINT_ADDRESS",
    projectName: "My Web3 Project",
    preferredCompanyNames: ["My Project Inc", "My Project Labs", "My Project Foundation"],
    incorporationShareBasisPoint: 3000, // 30% incorporation share
    founders: [
        {
            firstName: "Alice",
            lastName: "Smith",
            email: "alice@example.com",
            nationalityCountry: "USA",
            taxResidencyCountry: "USA",
            residentialAddress: "123 Main St, New York, NY 10001",
            shareBasisPoint: 4000, // 40%
        },
        {
            firstName: "Bob",
            lastName: "Johnson",
            email: "bob@example.com",
            nationalityCountry: "GBR",
            taxResidencyCountry: "GBR",
            residentialAddress: "456 High St, London, UK",
            shareBasisPoint: 3000, // 30%
        },
        // Total: 4000 + 3000 + 3000 (incorporation) = 10000 (100%)
    ],
    category: "DEFI",
    twitterHandle: "myproject",
    payWithSol: false,
});

// 2. After founders have completed their forms, check readiness:
// checkIncorporationStatus("YOUR_TOKEN_MINT_ADDRESS");

// 3. Once isReadyForIncorporation is true, start the process:
// startIncorporationProcess("YOUR_TOKEN_MINT_ADDRESS");
```

## 3. Understanding Share Allocation

The incorporation share and all founder shares are expressed in **basis points** (1 bps = 0.01%). The total must always equal exactly **10,000 bps (100%)**.

| Parameter                        | Range     | Description                               |
| -------------------------------- | --------- | ----------------------------------------- |
| `incorporationShareBasisPoint`   | 2000–3000 | The incorporation entity's share (20–30%) |
| Each founder's `shareBasisPoint` | 0–10000   | Each founder's ownership share            |

**The rule**: Sum of all founder `shareBasisPoint` values + `incorporationShareBasisPoint` = **10,000**.

Here are some valid allocation examples:

| Founders   | Founder Shares           | Incorporation Share | Total |
| ---------- | ------------------------ | ------------------- | ----- |
| 1 founder  | 7000 (70%)               | 3000 (30%)          | 10000 |
| 2 founders | 4000 + 3000 (70%)        | 3000 (30%)          | 10000 |
| 3 founders | 3000 + 3000 + 2000 (80%) | 2000 (20%)          | 10000 |

<Note>
  You can have between **1 and 10 founders** per incorporation. Each founder must provide a valid email, ISO 3166-1 alpha-3 country codes for nationality and tax residency (e.g. `USA`, `GBR`, `DEU`), and a residential address.
</Note>

## 4. Payment Options

The `payWithSol` parameter controls how the incorporation fee is paid:

| `payWithSol`      | Behavior                                                                                                                                    |
| ----------------- | ------------------------------------------------------------------------------------------------------------------------------------------- |
| `false` (default) | The payer pays directly in USDC. The wallet must hold enough USDC to cover the fee.                                                         |
| `true`            | The payment transaction performs an exact-output swap from SOL to USDC, matching the required USDC amount. The wallet must hold enough SOL. |

In both cases, the `priceUSDC` field in the response reflects the incorporation price in USDC. When paying with SOL, the transaction handles the swap automatically — no extra steps are needed.

## 5. Understanding Founder Forms

After you submit incorporation details, each founder in the response will have a **`formUrl`** — a unique URL where the founder completes all required verification steps (KYC, PEP questionnaire, and IP attribution acknowledgment).

Each founder must open their `formUrl` and complete all required fields.

The project's `isReadyForIncorporation` flag becomes `true` only when **every founder** has completed their form.

You can check individual founder progress at any time using `checkIncorporationStatus()` (which calls `sdk.incorporation.getDetails()` and `sdk.incorporation.list()` under the hood).

## 6. Run Your Script

The script has three functions you call at different stages. Update the bottom of `incorporate-token.ts` to uncomment the function you need, then run:

```bash theme={null}
npx ts-node incorporate-token.ts
```

**Stage 1** — Create payment and submit details (uncommented by default):

```typescript theme={null}
createPaymentAndSubmitDetails({ ... });
```

This pays the incorporation fee, submits founder details, and prints out the form URLs that each founder needs to complete.

**Stage 2** — After founders have completed their forms, check readiness:

```typescript theme={null}
checkIncorporationStatus("YOUR_TOKEN_MINT_ADDRESS");
```

This shows the current status and whether each founder has completed KYC, PEP, and IP attribution.

**Stage 3** — Once `isReadyForIncorporation` is `true`, start the incorporation:

```typescript theme={null}
startIncorporationProcess("YOUR_TOKEN_MINT_ADDRESS");
```

<Note>
  Founders may take hours or days to complete their forms. You can call `checkIncorporationStatus()` as many times as needed to monitor progress before triggering the final step.
</Note>

## Alternative: Using the Bags CLI

<Note>
  This section requires the Bags CLI. See [Install and Set Up the Bags CLI](/cli/install-and-setup) to get started.
</Note>

You can manage the incorporation flow directly from the terminal:

**Start payment:**

```bash theme={null}
bags incorporation pay --mint TOKEN_MINT
```

**Submit incorporation details:**

```bash theme={null}
bags incorporation submit \
  --mint TOKEN_MINT \
  --company-name "My Company LLC" \
  --founders '[{"name":"Alice","role":"CEO"}]' \
  --category "DeFi"
```

**Start the incorporation process (after all founders complete forms):**

```bash theme={null}
bags incorporation start --mint TOKEN_MINT
```

**List your incorporation projects:**

```bash theme={null}
bags incorporation list
```

**Check details for a specific token:**

```bash theme={null}
bags incorporation details --mint TOKEN_MINT
```

## 7. Troubleshooting

Common errors you may encounter:

* **Share basis points don't sum to 10000**: The sum of all founder `shareBasisPoint` values plus `incorporationShareBasisPoint` must equal exactly 10,000.
* **Incorporation share out of range**: `incorporationShareBasisPoint` must be between 2000 (20%) and 3000 (30%).
* **Invalid country code**: Nationality and tax residency must use ISO 3166-1 alpha-3 codes (3 letters, e.g. `USA`, `GBR`, `DEU`).
* **Invalid payer wallet**: Ensure the wallet address is a valid Solana public key.
* **Insufficient funds**: The payer wallet needs enough SOL or USDC to cover the incorporation fee.
* **Payment not confirmed**: The payment transaction must be confirmed on-chain before submitting incorporation details.
* **Prerequisites not met**: `startIncorporation` will fail if any founder hasn't completed KYC, PEP forms, or IP attribution.
* **Too many/few founders**: You must have between 1 and 10 founders.
* **Company names**: You must provide exactly 3 preferred company names.

Check the console output for detailed error messages.

## Related

* [API Reference — Create Incorporation Payment](/api-reference/create-incorporation-payment)
* [API Reference — Submit Incorporation Details](/api-reference/create-incorporation)
* [API Reference — Start Incorporation Process](/api-reference/start-incorporation)
* [API Reference — List Incorporation Projects](/api-reference/get-incorporation-list)
* [API Reference — Get Incorporation Details](/api-reference/get-incorporation-details)
* [Launch a Token](/how-to-guides/launch-token)
