# Post

The POST methods are completely free to use. Subs take care of the transaction fees. Your customers can now subscribe almost for free. They still need to pay the approval call.&#x20;

{% hint style="info" %}
Please, note that you need super access to call these methods. If you don't have it yet, write to [us](https://t.me/+esGoPJGnaXE2ODNk) to get it.
{% endhint %}

For the first call the signature must come from the subscriber wallet

## Gasless Subscription

<mark style="color:green;">`POST`</mark> `https://api.subsprotocol.com/creator/subscribe`

#### Request Body

| Name                                                | Type   | Description                                     |
| --------------------------------------------------- | ------ | ----------------------------------------------- |
| appId<mark style="color:red;">\*</mark>             | String | App ID                                          |
| chain<mark style="color:red;">\*</mark>             | String | Chain Name                                      |
| user<mark style="color:red;">\*</mark>              | String | User Address                                    |
| token<mark style="color:red;">\*</mark>             | String | Token Address                                   |
| paymentId<mark style="color:red;">\*</mark>         | String | Payment ID                                      |
| sig<mark style="color:red;">\*</mark>               | String | Signature of appId, paymentId, token and nonce. |
| userChoosenPeriod<mark style="color:red;">\*</mark> | String | Choosen duration of subscriptions               |

<br>

## Gasless add Payment to an App

Here the signature must come from the creator of the application.

```typescript
// Payment types

enum PeriodType {
    // 0: One Time Payment (No Subscription)
    ONETIME,
    // 1: Minutes Subscription
    MINUTES,
    // 2: Hours Subscription
    HOURS,
    // 3: Days Subscription
    DAYS,
    // 4: Week Subscription
    WEEK,
    // 5: Month subscriptions
    MONTH,
    // 6: Year subscriptions
    YEAR
}

interface PaymentToken {
  token: string; // Identifier of the token, usually an Ethereum erc-20 address
  price: string; // Price (with decimals) associated with this token, expressed as a string to avoid precision issues with large numbers
  firstAmount: string; // Initial amount ( ideally for payment split, if you want the first payment to be différent than the subscription amount), also expressed as a string for the same precision reasons
}

interface Payment {
  name: string; // Name, encoded in hexadecimal
  owner: string; // Ethereum address of the owner of the payment
  fee: number; // Associated fee ( add fee if you're not the owner of the payment and you wanna take the fees from this payment, can be used for affiliation) 50 = 5%
  paymentType: number; // Type of payment, represented by a number ( 0 = erc-20 payment )
  paymentTokens: PaymentToken[]; // List of possible payment tokens for this payment
  trialPeriod: number; // Duration of the trial period, expressed in number of days
  periodType: number; // Type of period, likely an enum indicating units like days, months, etc.
  limitPeriod: number; // minimum time for user to approve before subscription
  loadingTime: number; // The time, Subs system have to wait before considering subscription as expired ( In days )
}

```

<mark style="color:green;">`POST`</mark> `https://api.subsprotocol.com/creator/addPayment`

#### Headers

| Name                                        | Type   | Description |
| ------------------------------------------- | ------ | ----------- |
| x-api-key<mark style="color:red;">\*</mark> | String | API Key     |

#### Request Body

| Name                                        | Type       | Description                              |
| ------------------------------------------- | ---------- | ---------------------------------------- |
| appId<mark style="color:red;">\*</mark>     | String     | App ID                                   |
| chain<mark style="color:red;">\*</mark>     | String     | Chain Name                               |
| appOwner<mark style="color:red;">\*</mark>  | String     | AppOwner address                         |
| version<mark style="color:red;">\*</mark>   | String     | Depends of the chain: testnet or mainnet |
| payments <mark style="color:red;">\*</mark> | Payment\[] | List of Payments                         |
| sig<mark style="color:red;">\*</mark>       | String     | Signature of the appId and payments      |

{% tabs %}
{% tab title="200: OK All fine" %}

```
{
    "success": "true",
    "message": "Payment successfully added"
}
```

{% endtab %}

{% tab title="400: Bad Request Wrong payments" %}

```
{
    "success": "false",
    "error": "Contract Execution Error",
    "message": "åm*®StudentStudent"
}

```

{% endtab %}
{% endtabs %}

Here you have a template for your addPayment request.\
\
Watch up the name is a string converted in Bytes32\
You can try to convert here for your tests.  <https://www.devoven.com/string-to-bytes32>

<table><thead><tr><th width="189">Variables</th><th width="175.33333333333331">Types</th><th>Description</th></tr></thead><tbody><tr><td>name</td><td><pre class="language-solidity"><code class="lang-solidity">string
</code></pre></td><td>Name of your app in Hexadecimal</td></tr><tr><td>owner</td><td><pre class="language-solidity"><code class="lang-solidity">string
</code></pre></td><td>Address of the beneficiary of the fees for this payment</td></tr><tr><td>fee</td><td><pre class="language-solidity" data-full-width="true"><code class="lang-solidity">uint
</code></pre></td><td>Percent given to the owner of this payment</td></tr><tr><td>paymentType</td><td><pre class="language-solidity"><code class="lang-solidity">uint
</code></pre></td><td>MUST be 0 for ERC20 token                            We will SOON add ERC721 token</td></tr><tr><td>periodType</td><td><pre class="language-solidity"><code class="lang-solidity">uint
</code></pre></td><td><p>- 0 for One Time Payement                       </p><p>- 1 for Minute Payment</p><p>- 2 for Hour Payment                             </p><p>- 3 for Day Payment                            </p><p>- 4 for Week Payment                             </p><p>- 5 for Month Payment                             </p><p>- 6 for Year Payment</p></td></tr><tr><td>trialPeriod</td><td><pre class="language-solidity"><code class="lang-solidity">uint
</code></pre></td><td>Number of periodType given for free to the customer</td></tr><tr><td>limitPeriod</td><td><pre class="language-solidity"><code class="lang-solidity">uint
</code></pre></td><td>Number of debit, but also used for the approval needed to subscribe</td></tr><tr><td>loadingTime</td><td><pre class="language-solidity"><code class="lang-solidity">uint
</code></pre></td><td>Number of extra Days customers have if the debt didn't worked</td></tr></tbody></table>

Here is how you can make you own signature.

```javascript
const { ethers } = require("ethers");

// Example input data
const data = {
    appId: "41",
    chain: "Binance Smart Chain Testnet",
    appOwner: "0x7bFD3D3E0c1cD1e8a92eFd8de2E5769D9a39497B",
    version: "testnet" or "mainnet",
    payments: [
        {
            name: "0x53747564656e7400000000000000000000000000000000000000000000000000",
            owner: "0x7bFD3D3E0c1cD1e8a92eFd8de2E5769D9a39497B",
            fee: 2,
            paymentType: 0,
            paymentTokens: [
                {
                    token: "0xfe4F5145f6e09952a5ba9e956ED0C25e3Fa4c7F1",
                    price: "20000000",
                    firstAmount: "25000000",
                }
            ],
            trialPeriod: 0,
            periodType: 1,
            limitPeriod: 3,
            loadingTime: 5
        }
    ]
};

// Signer's private key (replace with the actual private key)
const privateKey = "0x....";

function computeHash(appId, payments) {
    const paymentNames = payments.map(payment => payment.name); // Extract payment names

    // Mimic abi.encodePacked(_appId, paymentNames)
    const encoded = ethers.utils.solidityPack(
        ["uint256", "bytes32[]"],
        [ethers.BigNumber.from(appId), paymentNames]
    );
    // Compute keccak256 hash
    return ethers.utils.keccak256(encoded);
}



// Step 2: Sign the hash
async function signHash() {
    // Create a signer from the private key
    const wallet = new ethers.Wallet(privateKey);

    // Compute the message hash
    const messageHash = computeHash(data.appId, data.payments); 
    
    // Sign the hash
    let signature = await wallet.signMessage(ethers.utils.arrayify(messageHash));
    console.log("Computed Hash:", messageHash);
    console.log("Signature:", signature);
}

// Call the function
signHash().catch(err => console.error(err));
```


---

# Agent Instructions: 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:

```
GET https://docs.subsprotocol.com/developer-docs/api/post.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
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.
