> For the complete documentation index, see [llms.txt](https://docs.xdao.app/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.xdao.app/xdao-ton-api-reference/crowdfunding.md).

# Crowdfunding

Campaign-scoped helpers for crowdfunding integrators. The DAO bearer token must be issued for the DAO that owns the campaign in the path.

## Contribution deeplink

> Returns a ready-to-sign \`ton://transfer/...\` URI that contributes the\
> given \`amount\` to the specified crowdfunding campaign.\
> \
> Auth: the DAO bearer token's \`dao\_address\` must match the DAO that\
> owns the campaign. Mismatches return 403.<br>

```json
{"openapi":"3.0.3","info":{"title":"XDAO TON API docs","version":"1.1.0"},"tags":[{"name":"Crowdfunding","description":"Campaign-scoped helpers for crowdfunding integrators. The DAO bearer token\nmust be issued for the DAO that owns the campaign in the path.\n"}],"servers":[{"url":"https://ton.xdao.app"}],"security":[{"DaoBearerAuth":[]}],"components":{"securitySchemes":{"DaoBearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"JWT","description":"DAO service token in Bearer format.\nThe token must be valid, not revoked, and authorized for the same `dao_address` as in path.\n"}},"parameters":{"CampaignAddressPath":{"name":"address","in":"path","required":true,"description":"Crowdfunding master address. Any TON format is accepted (raw `0:hex`,\n`EQ.../UQ.../kQ.../0Q...`, base64-url or standard base64).\n","schema":{"type":"string"}},"ContributionAmountQuery":{"name":"amount","in":"query","required":true,"description":"Contribution amount in the smallest units of the campaign currency:\nnanoTON for native campaigns, jetton smallest-units (e.g. `1000000`\n= 1 USDT for 6-decimal USDT) for jetton campaigns. Must satisfy\n`minAmountPerUser <= amount <= maxAmountPerUser`.\n","schema":{"type":"string","pattern":"^[0-9]+$"}},"ContributionInvestorAddressQuery":{"name":"investor_address","in":"query","required":false,"description":"Investor's TON wallet address. Required for jetton campaigns — used\nto resolve the investor's jetton wallet via `get_wallet_address` on\nthe jetton master. Ignored for native campaigns.\n","schema":{"type":"string"}},"ContributionQueryIDQuery":{"name":"query_id","in":"query","required":false,"description":"TON message `query_id` (uint64). Defaults to 0.","schema":{"type":"integer","format":"int64","minimum":0,"default":0}},"ContributionResponseAddressQuery":{"name":"response_address","in":"query","required":false,"description":"Optional override for `response_destination` in the jetton-transfer\nbody. Defaults to `investor_address` if absent. Has no effect on\nnative campaigns.\n","schema":{"type":"string"}}},"schemas":{"ContributionLink":{"type":"object","required":["isNative","campaignAddress","tonTransfer","details","warnings"],"properties":{"isNative":{"type":"boolean","description":"`true` for native TON campaigns, `false` for jetton campaigns."},"campaignAddress":{"type":"string","description":"Address that the `ton://transfer/` URI sends the message to (bounceable\nmainnet form). For jetton campaigns this is the *investor's* jetton\nwallet, **not** the campaign master.\n"},"tonTransfer":{"type":"object","required":["uri"],"properties":{"uri":{"type":"string","description":"Ready-to-sign `ton://transfer/{to}?amount={nanoton}&bin={base64url}`\nURI. Open it in a TON wallet (Tonkeeper et al.) to sign — no further\nmanipulation should be necessary.\n"}}},"details":{"type":"object","description":"Same payload as `tonTransfer.uri`, but pre-decoded for clients that\nprefer to construct the transaction themselves (e.g. TonConnect).\n","required":["to","valueNanoton","bodyBocBase64Url"],"properties":{"to":{"type":"string","description":"Destination address (bounceable mainnet)."},"valueNanoton":{"type":"string","description":"Message value in nanoTON as a decimal string."},"bodyBocBase64Url":{"type":"string","description":"Message body BoC, base64url-encoded (no padding)."}}},"miniAppLink":{"type":"string","description":"Optional Telegram Mini-App deeplink that opens this campaign in the\nXDAO bot — bonus convenience for integrators.\n"},"warnings":{"type":"array","description":"Non-fatal signals. The transaction is still served. Known values:\n- `whitelist_enforced_on_chain` — campaign has a whitelist; on-chain\n  `throw` will reject contributors not on it.\n- `amount_exceeds_remaining_hardcap` — `amount > hardCap - totalAmount`.\n","items":{"type":"string"}}}},"Error":{"type":"object","required":["error"],"properties":{"error":{"type":"string"}}}},"responses":{"BadRequest":{"description":"Request is malformed. Error codes used by `/contribution-link`:\n- `invalid_campaign_address` — campaign path segment cannot be parsed\n- `invalid_amount` — amount is not a positive integer, or outside\n  `[minAmountPerUser, maxAmountPerUser]`\n- `missing_investor_address` — jetton campaign called without\n  `investor_address`\n- `invalid_investor_address` / `invalid_response_address` — address\n  cannot be parsed\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"UnauthorizedError":{"description":"Token is missing, invalid, expired, or revoked.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"Forbidden":{"description":"Token does not have access to this DAO or endpoint.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"NotFound":{"description":"Requested resource was not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"Conflict":{"description":"Campaign is in a state that cannot accept contributions. Error codes:\n- `campaign_paused` — admin has paused the campaign\n- `campaign_inactive` — `status != active` (already successful, failed,\n  or emergency-withdrawn)\n- `campaign_ended` — `end_time` has passed\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"InternalError":{"description":"Internal server error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"BadGateway":{"description":"Upstream blockchain RPC failure. Error codes:\n- `jetton_wallet_lookup_failed` — `get_wallet_address` against the\n  jetton master failed (liteserver issue, contract not deployed, etc.)\n- `jetton_resolver_unavailable` — the API instance was started without\n  a liteclient and cannot serve jetton campaigns\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"paths":{"/api/v1/crowdfunding/campaigns/{address}/contribution-link":{"get":{"tags":["Crowdfunding"],"summary":"Contribution deeplink","description":"Returns a ready-to-sign `ton://transfer/...` URI that contributes the\ngiven `amount` to the specified crowdfunding campaign.\n\nAuth: the DAO bearer token's `dao_address` must match the DAO that\nowns the campaign. Mismatches return 403.\n","operationId":"getContributionLink","parameters":[{"$ref":"#/components/parameters/CampaignAddressPath"},{"$ref":"#/components/parameters/ContributionAmountQuery"},{"$ref":"#/components/parameters/ContributionInvestorAddressQuery"},{"$ref":"#/components/parameters/ContributionQueryIDQuery"},{"$ref":"#/components/parameters/ContributionResponseAddressQuery"}],"responses":{"200":{"description":"Contribution link payload","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ContributionLink"}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/UnauthorizedError"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"409":{"$ref":"#/components/responses/Conflict"},"500":{"$ref":"#/components/responses/InternalError"},"502":{"$ref":"#/components/responses/BadGateway"}}}}}}
```

## LP claim deeplink

> Returns a ready-to-sign \`ton://transfer/...\` URI for the \*\*initial\*\* LP\
> claim. This is the \`request\_claim\_lp\_tokens\` message the investor sends to\
> their per-campaign Helper contract once the campaign is \`successful\`.\
> \
> Auth: the DAO bearer token's \`dao\_address\` must match the DAO that owns the\
> campaign. Mismatches return 403.<br>

```json
{"openapi":"3.0.3","info":{"title":"XDAO TON API docs","version":"1.1.0"},"tags":[{"name":"Crowdfunding","description":"Campaign-scoped helpers for crowdfunding integrators. The DAO bearer token\nmust be issued for the DAO that owns the campaign in the path.\n"}],"servers":[{"url":"https://ton.xdao.app"}],"security":[{"DaoBearerAuth":[]}],"components":{"securitySchemes":{"DaoBearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"JWT","description":"DAO service token in Bearer format.\nThe token must be valid, not revoked, and authorized for the same `dao_address` as in path.\n"}},"parameters":{"CampaignAddressPath":{"name":"address","in":"path","required":true,"description":"Crowdfunding master address. Any TON format is accepted (raw `0:hex`,\n`EQ.../UQ.../kQ.../0Q...`, base64-url or standard base64).\n","schema":{"type":"string"}},"ClaimOwnerAddressQuery":{"name":"owner_address","in":"query","required":true,"description":"Investor wallet address claiming LP tokens. Any TON format is accepted\n(raw `0:hex`, `EQ.../UQ.../kQ.../0Q...`, base64-url or standard base64).\n","schema":{"type":"string"}},"ContributionQueryIDQuery":{"name":"query_id","in":"query","required":false,"description":"TON message `query_id` (uint64). Defaults to 0.","schema":{"type":"integer","format":"int64","minimum":0,"default":0}}},"schemas":{"ClaimLink":{"type":"object","description":"Ready-to-sign deeplink for an LP claim. \n","required":["kind","campaignAddress","tonTransfer","details","warnings"],"properties":{"kind":{"type":"string","description":"Which claim this link performs.","enum":["initial","vesting"]},"campaignAddress":{"type":"string","description":"Bounceable mainnet form of the crowdfunding master address."},"tonTransfer":{"type":"object","required":["uri"],"properties":{"uri":{"type":"string","description":"Ready-to-sign `ton://transfer/{to}?amount={nanoton}&bin={base64url}`\nURI. For `kind=initial` `to` is the Helper; for `kind=vesting` the\nVestingVault.\n"}}},"details":{"type":"object","description":"Same payload as `tonTransfer.uri`, pre-decoded for clients that prefer\nto construct the transaction themselves (e.g. TonConnect).\n","required":["to","valueNanoton","bodyBocBase64Url"],"properties":{"to":{"type":"string","description":"Destination address (bounceable mainnet) — Helper or VestingVault."},"valueNanoton":{"type":"string","description":"Message value in nanoTON as a decimal string."},"bodyBocBase64Url":{"type":"string","description":"Message body BoC, base64url-encoded (no padding)."}}},"vesting":{"type":"object","description":"Present only for `kind=vesting`. An **estimate** of the claimable LP and\nthe current vesting phase; the exact amount is computed on-chain by the\nvault at execution time.\n","required":["phase","claimableAmount","vestedAmount","totalLpAmount","claimedLpAmount"],"properties":{"phase":{"type":"string","description":"Vesting phase at the time of the request.","enum":["not_started","cliff","vesting","fully_vested","emergency"]},"claimableAmount":{"type":"string","description":"Estimated claimable LP (vested minus already claimed), smallest units."},"vestedAmount":{"type":"string","description":"Estimated total vested LP so far, smallest units."},"totalLpAmount":{"type":"string","description":"Total LP allocated to the investor, smallest units."},"claimedLpAmount":{"type":"string","description":"LP already claimed, smallest units."},"vestingEnd":{"type":"string","format":"date-time","description":"Computed end = vestingStart + vestingDuration."}}},"warnings":{"type":"array","description":"Non-fatal signals. The transaction is still served. Known values:\n- `nothing_claimable_now` — estimated claimable amount is 0 (e.g. before\n  TGE or between linear ticks). Signing it will fail the vault's\n  `nothing_to_claim` guard.\n","items":{"type":"string"}}}},"Error":{"type":"object","required":["error"],"properties":{"error":{"type":"string"}}}},"responses":{"BadRequest":{"description":"Request is malformed. Error codes used by `/contribution-link`:\n- `invalid_campaign_address` — campaign path segment cannot be parsed\n- `invalid_amount` — amount is not a positive integer, or outside\n  `[minAmountPerUser, maxAmountPerUser]`\n- `missing_investor_address` — jetton campaign called without\n  `investor_address`\n- `invalid_investor_address` / `invalid_response_address` — address\n  cannot be parsed\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"UnauthorizedError":{"description":"Token is missing, invalid, expired, or revoked.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"Forbidden":{"description":"Token does not have access to this DAO or endpoint.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"NotFound":{"description":"Requested resource was not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"Conflict":{"description":"Campaign is in a state that cannot accept contributions. Error codes:\n- `campaign_paused` — admin has paused the campaign\n- `campaign_inactive` — `status != active` (already successful, failed,\n  or emergency-withdrawn)\n- `campaign_ended` — `end_time` has passed\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"InternalError":{"description":"Internal server error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"paths":{"/api/v1/crowdfunding/campaigns/{address}/claim-link":{"get":{"tags":["Crowdfunding"],"summary":"LP claim deeplink","description":"Returns a ready-to-sign `ton://transfer/...` URI for the **initial** LP\nclaim. This is the `request_claim_lp_tokens` message the investor sends to\ntheir per-campaign Helper contract once the campaign is `successful`.\n\nAuth: the DAO bearer token's `dao_address` must match the DAO that owns the\ncampaign. Mismatches return 403.\n","operationId":"getClaimLink","parameters":[{"$ref":"#/components/parameters/CampaignAddressPath"},{"$ref":"#/components/parameters/ClaimOwnerAddressQuery"},{"$ref":"#/components/parameters/ContributionQueryIDQuery"}],"responses":{"200":{"description":"Claim link payload","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ClaimLink"}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/UnauthorizedError"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"409":{"$ref":"#/components/responses/Conflict"},"500":{"$ref":"#/components/responses/InternalError"}}}}}}
```

## Vested LP claim deeplink

> Returns a ready-to-sign \`ton://transfer/...\` URI for the \`claim\_vested\`\
> message the investor sends to their per-campaign VestingVault to release the\
> currently vested-but-unclaimed LP.\
> \
> Auth: the DAO bearer token's \`dao\_address\` must match the DAO that owns the\
> campaign. Mismatches return 403.<br>

```json
{"openapi":"3.0.3","info":{"title":"XDAO TON API docs","version":"1.1.0"},"tags":[{"name":"Crowdfunding","description":"Campaign-scoped helpers for crowdfunding integrators. The DAO bearer token\nmust be issued for the DAO that owns the campaign in the path.\n"}],"servers":[{"url":"https://ton.xdao.app"}],"security":[{"DaoBearerAuth":[]}],"components":{"securitySchemes":{"DaoBearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"JWT","description":"DAO service token in Bearer format.\nThe token must be valid, not revoked, and authorized for the same `dao_address` as in path.\n"}},"parameters":{"CampaignAddressPath":{"name":"address","in":"path","required":true,"description":"Crowdfunding master address. Any TON format is accepted (raw `0:hex`,\n`EQ.../UQ.../kQ.../0Q...`, base64-url or standard base64).\n","schema":{"type":"string"}},"ClaimOwnerAddressQuery":{"name":"owner_address","in":"query","required":true,"description":"Investor wallet address claiming LP tokens. Any TON format is accepted\n(raw `0:hex`, `EQ.../UQ.../kQ.../0Q...`, base64-url or standard base64).\n","schema":{"type":"string"}},"ContributionQueryIDQuery":{"name":"query_id","in":"query","required":false,"description":"TON message `query_id` (uint64). Defaults to 0.","schema":{"type":"integer","format":"int64","minimum":0,"default":0}}},"schemas":{"ClaimLink":{"type":"object","description":"Ready-to-sign deeplink for an LP claim. \n","required":["kind","campaignAddress","tonTransfer","details","warnings"],"properties":{"kind":{"type":"string","description":"Which claim this link performs.","enum":["initial","vesting"]},"campaignAddress":{"type":"string","description":"Bounceable mainnet form of the crowdfunding master address."},"tonTransfer":{"type":"object","required":["uri"],"properties":{"uri":{"type":"string","description":"Ready-to-sign `ton://transfer/{to}?amount={nanoton}&bin={base64url}`\nURI. For `kind=initial` `to` is the Helper; for `kind=vesting` the\nVestingVault.\n"}}},"details":{"type":"object","description":"Same payload as `tonTransfer.uri`, pre-decoded for clients that prefer\nto construct the transaction themselves (e.g. TonConnect).\n","required":["to","valueNanoton","bodyBocBase64Url"],"properties":{"to":{"type":"string","description":"Destination address (bounceable mainnet) — Helper or VestingVault."},"valueNanoton":{"type":"string","description":"Message value in nanoTON as a decimal string."},"bodyBocBase64Url":{"type":"string","description":"Message body BoC, base64url-encoded (no padding)."}}},"vesting":{"type":"object","description":"Present only for `kind=vesting`. An **estimate** of the claimable LP and\nthe current vesting phase; the exact amount is computed on-chain by the\nvault at execution time.\n","required":["phase","claimableAmount","vestedAmount","totalLpAmount","claimedLpAmount"],"properties":{"phase":{"type":"string","description":"Vesting phase at the time of the request.","enum":["not_started","cliff","vesting","fully_vested","emergency"]},"claimableAmount":{"type":"string","description":"Estimated claimable LP (vested minus already claimed), smallest units."},"vestedAmount":{"type":"string","description":"Estimated total vested LP so far, smallest units."},"totalLpAmount":{"type":"string","description":"Total LP allocated to the investor, smallest units."},"claimedLpAmount":{"type":"string","description":"LP already claimed, smallest units."},"vestingEnd":{"type":"string","format":"date-time","description":"Computed end = vestingStart + vestingDuration."}}},"warnings":{"type":"array","description":"Non-fatal signals. The transaction is still served. Known values:\n- `nothing_claimable_now` — estimated claimable amount is 0 (e.g. before\n  TGE or between linear ticks). Signing it will fail the vault's\n  `nothing_to_claim` guard.\n","items":{"type":"string"}}}},"Error":{"type":"object","required":["error"],"properties":{"error":{"type":"string"}}}},"responses":{"BadRequest":{"description":"Request is malformed. Error codes used by `/contribution-link`:\n- `invalid_campaign_address` — campaign path segment cannot be parsed\n- `invalid_amount` — amount is not a positive integer, or outside\n  `[minAmountPerUser, maxAmountPerUser]`\n- `missing_investor_address` — jetton campaign called without\n  `investor_address`\n- `invalid_investor_address` / `invalid_response_address` — address\n  cannot be parsed\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"UnauthorizedError":{"description":"Token is missing, invalid, expired, or revoked.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"Forbidden":{"description":"Token does not have access to this DAO or endpoint.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"NotFound":{"description":"Requested resource was not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"Conflict":{"description":"Campaign is in a state that cannot accept contributions. Error codes:\n- `campaign_paused` — admin has paused the campaign\n- `campaign_inactive` — `status != active` (already successful, failed,\n  or emergency-withdrawn)\n- `campaign_ended` — `end_time` has passed\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"InternalError":{"description":"Internal server error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"paths":{"/api/v1/crowdfunding/campaigns/{address}/vesting-claim-link":{"get":{"tags":["Crowdfunding"],"summary":"Vested LP claim deeplink","description":"Returns a ready-to-sign `ton://transfer/...` URI for the `claim_vested`\nmessage the investor sends to their per-campaign VestingVault to release the\ncurrently vested-but-unclaimed LP.\n\nAuth: the DAO bearer token's `dao_address` must match the DAO that owns the\ncampaign. Mismatches return 403.\n","operationId":"getVestingClaimLink","parameters":[{"$ref":"#/components/parameters/CampaignAddressPath"},{"$ref":"#/components/parameters/ClaimOwnerAddressQuery"},{"$ref":"#/components/parameters/ContributionQueryIDQuery"}],"responses":{"200":{"description":"Vesting claim link payload","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ClaimLink"}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/UnauthorizedError"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"409":{"$ref":"#/components/responses/Conflict"},"500":{"$ref":"#/components/responses/InternalError"}}}}}}
```


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://docs.xdao.app/xdao-ton-api-reference/crowdfunding.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
