Commit via API¶
Before performing commits, the initial registration should have been performed in order to make sure the accessibility of the content file from the decentralized web.
Creating commits via API is the simplest way to preserve the asset history. Here is an example of how you can use the curl command to make a POST request using your Capture Token and the Nid of the asset you want to commit. If you do not already have a Capture Token yet, please follow the instruction provided to create one. The More Tools page shows more examples of how to work with Numbers APIs.
If you opt to use the API for committing, the committer will be the wallet of the Numbers Protocol, 0x51130dB91B91377A24d6Ebeb2a5fC02748b53ce1. However, if you prefer to have a custom committer, you can commit via nit module. This flexibility allows you to tailor your commit process to best suit your needs.
The author will still be your Capture Wallet. Anyone can trust that you created the Asset Tree by verifying the Asset Tree sha256 checksum and signature, which will result in your Capture Wallet address being displayed as the verification result.
The Numbers API is a pay-as-you-go system, which means you only pay for the commit orders you create. This is a cost-effective way to use the API and it allows you to control your expenses. Make sure to top up and ensure sufficient funds in your wallet in the form of Credits or NUM to cover the cost. Payment for services is processed using NUM; if you want to know how much it costs in USD, you can check CoinGecko or CoinMarketCap.
Endpoint¶
Submit commit:
POST https://api.numbersprotocol.io/api/v3/nit/commit/
Check commit status:
GET https://api.numbersprotocol.io/api/v3/nit/commit/{order_id}/
Cost: 0.1 NUM per commit order + gas.
The commit API is asynchronous. A new commit request usually returns 202 Accepted with an order_id. Use the status endpoint to poll the order until it returns 200 OK with the final transaction hash.
Headers¶
Authorization: token YOUR_CAPTURE_TOKEN
Content-Type: application/json
Idempotency-Key: YOUR_UNIQUE_COMMIT_KEY
Authorization and Content-Type are required. Idempotency-Key is strongly recommended so retried requests do not create duplicate commit orders. Use the same idempotency key when retrying the same logical commit, and use a different key for a different commit. If your integration has a Numbers API key, you may also include X-Api-Key.
Keep your Capture Token secure. Do not embed it in publicly distributed client code.
Request Body¶
Required fields:
| Field | Type | Description |
|---|---|---|
encodingFormat |
string | MIME type of the asset being committed. |
assetCid |
string | Nid of the asset being committed. |
assetTimestampCreated |
integer | Unix timestamp of when the asset was created. |
assetCreator |
string | Name of the creator of the asset. |
assetSha256 |
string | SHA-256 checksum of the asset being committed. |
Optional fields:
| Field | Type | Description |
|---|---|---|
testnet |
boolean | Set to true to commit on testnet. |
author |
string | Ethereum address of the author of the commit. |
licenseName |
string | Name of the asset license. |
licenseDocument |
string | Document URL or text for the asset license. |
custom |
object | Custom metadata in JSON object format. |
nftContractAddress |
string | Ethereum address of the NFT contract of the asset. Required when nftChainID is provided. |
nftChainID |
integer | Chain ID of the NFT contract. |
nftTokenID |
string | Token ID of the NFT. Required when nftChainID is provided. |
commitMessage |
string | Description of this commit. |
action |
string | The action performed. See Action. |
abstract |
string | Asset description or caption. |
headline |
string | Headline or title of the content file. |
Submit a Commit¶
curl -X POST "https://api.numbersprotocol.io/api/v3/nit/commit/" \
-H "Content-Type: application/json" \
-H "Authorization: token YOUR_CAPTURE_TOKEN" \
-H "Idempotency-Key: example-asset-commit-001" \
-d '{
"encodingFormat": "image/jpeg",
"assetCid": "YOUR_ASSET_NID",
"assetTimestampCreated": 1674556617,
"assetCreator": "Example User",
"assetSha256": "32ff5bc7ec494005c01df4a8da67f7ef5a95037de2f7863e3d463b4697447739",
"abstract": "My first Web3.0 asset",
"testnet": true,
"commitMessage": "My first commit",
"custom": {"usedBy": "https://numbersprotocol.io"}
}'
If the commit is accepted for processing, the response is:
{
"status": "processing",
"error": "Commit is processing for this idempotency key",
"order_id": "00000000-0000-0000-0000-000000000000"
}
The response also includes Retry-After: 30. Wait before polling when possible.
If the same Idempotency-Key already has a completed result, the submit endpoint may return 200 OK immediately with the final commit result.
Check Commit Status¶
curl -X GET "https://api.numbersprotocol.io/api/v3/nit/commit/ORDER_ID/" \
-H "Authorization: token YOUR_CAPTURE_TOKEN"
When the commit is still processing, the status endpoint returns 202 Accepted:
{
"status": "processing",
"error": "Commit is already processing for this idempotency key",
"order_id": "00000000-0000-0000-0000-000000000000"
}
When the commit is complete, the status endpoint returns 200 OK:
{
"txHash": "0x...",
"assetCid": "YOUR_ASSET_NID",
"assetTreeCid": "YOUR_ASSET_TREE_NID",
"explorer": "https://..."
}
Status Codes¶
| Status | Meaning |
|---|---|
200 |
Commit completed successfully. |
202 |
Commit accepted and still processing. Poll the status endpoint. |
400 |
Bad request, invalid request body, or stored commit failure caused by request/order state. |
401 |
Unauthorized. Check your Capture Token. |
403 |
Forbidden. The authenticated user does not have permission or sufficient account state for the operation. |
404 |
Commit order not found or not visible to the authenticated user. |
409 |
Idempotency key conflict. The key was already used with a different request body. |
500 |
Internal server error or stored commit failure. Retry later or contact support if it persists. |
The request body follows the spec of AssetTree. More examples can be found below:
Python¶
import time
import requests
SUBMIT_URL = "https://api.numbersprotocol.io/api/v3/nit/commit/"
# Replace these values with your own values.
CAPTURE_TOKEN = "YOUR_CAPTURE_TOKEN"
ASSET_NID = "YOUR_ASSET_NID"
IDEMPOTENCY_KEY = "example-asset-commit-001"
headers = {
"Content-Type": "application/json",
"Authorization": f"token {CAPTURE_TOKEN}",
"Idempotency-Key": IDEMPOTENCY_KEY,
}
data = {
"author": "0x8212099e5aF75e555A3E63da77a99CcC9527aCC1",
"encodingFormat": "image/jpeg",
"assetCid": ASSET_NID,
"assetTimestampCreated": 1674556617,
"assetCreator": "Example User",
"assetSha256": "32ff5bc7ec494005c01df4a8da67f7ef5a95037de2f7863e3d463b4697447739",
"abstract": "My first Web3.0 asset",
"commitMessage": "My first commit",
}
response = requests.post(SUBMIT_URL, headers=headers, json=data, timeout=30)
response.raise_for_status()
response_data = response.json()
if response.status_code == 200:
print(response_data["txHash"])
elif response.status_code == 202:
order_id = response_data["order_id"]
status_url = f"{SUBMIT_URL}{order_id}/"
poll_headers = {"Authorization": headers["Authorization"]}
for _ in range(20):
retry_after = int(response.headers.get("Retry-After", "30"))
time.sleep(retry_after)
status_response = requests.get(status_url, headers=poll_headers, timeout=30)
if status_response.status_code == 200:
print(status_response.json()["txHash"])
break
if status_response.status_code == 202:
response = status_response
continue
status_response.raise_for_status()
else:
raise TimeoutError(f"Commit order {order_id} is still processing")
else:
response.raise_for_status()
JavaScript¶
const submitUrl = "https://api.numbersprotocol.io/api/v3/nit/commit/";
// Replace these values with your own values.
const captureToken = "YOUR_CAPTURE_TOKEN";
const assetNid = "YOUR_ASSET_NID";
const idempotencyKey = "example-asset-commit-001";
const headers = {
"Content-Type": "application/json",
"Authorization": `token ${captureToken}`,
"Idempotency-Key": idempotencyKey
};
const data = {
"author": "0x8212099e5aF75e555A3E63da77a99CcC9527aCC1",
"encodingFormat": "image/jpeg",
"assetCid": assetNid,
"assetTimestampCreated": 1674556617,
"assetCreator": "Example User",
"assetSha256": "32ff5bc7ec494005c01df4a8da67f7ef5a95037de2f7863e3d463b4697447739",
"abstract": "My first Web3.0 asset"
};
function sleep(ms) {
return new Promise(resolve => setTimeout(resolve, ms));
}
async function submitCommit() {
let response = await fetch(submitUrl, {
method: "POST",
headers,
body: JSON.stringify(data)
});
if (!response.ok && response.status !== 202) {
throw new Error(`Commit request failed with HTTP ${response.status}`);
}
let responseData = await response.json();
if (response.status === 200) {
console.log(responseData.txHash);
return;
}
const orderId = responseData.order_id;
const statusUrl = `${submitUrl}${orderId}/`;
for (let i = 0; i < 20; i += 1) {
const retryAfter = Number(response.headers.get("Retry-After") || "30");
await sleep(retryAfter * 1000);
response = await fetch(statusUrl, {
method: "GET",
headers: {"Authorization": headers.Authorization}
});
if (response.status === 200) {
responseData = await response.json();
console.log(responseData.txHash);
return;
}
if (response.status !== 202) {
throw new Error(`Commit status check failed with HTTP ${response.status}`);
}
}
throw new Error(`Commit order ${orderId} is still processing`);
}
submitCommit().catch(error => {
console.error("Error:", error);
});
Note:
- Most fields are strings.
assetTimestampCreatedandnftChainIDare integers,testnetis a boolean, andcustomis a JSON object. - If
licenseNameorlicenseDocumentare not provided, both will be set to null, i.e. no license is specified. customfield must be a valid JSON object.assetSourceTypefield is determined by signature and service name associated with API key and theassetSourceTypeput incustomfield will be ignored.- If
nftChainIDis provided, bothnftContractAddressandnftTokenIDare required. - If
authoris not provided, it will be set to the Integrity Wallet of the user who calls the API .
Defining Provenance¶
The following table lists the key fields of the API which define the asset information.
| Field | Description | Limitation | Sample Value |
|---|---|---|---|
| abstract | Asset description or asset caption | 255 characters | My first Web3.0 asset |
| assetCreator | Creator of the asset | 21 characters | Alice Wu |
| licenseName | Asset license chosen | 21 characters | BY-NC-ND |
| integrityCid | The metadata Cid | IPFS Cid | bafkreifkyltf4sfduwp5mghyxckq7invzjwl3pl4mksiorshr7lm2y2n2y |
| assetTimestampCreated | Creation timestamp | Unix timestamp | 1674556617 |
| custom: usedBy | How asset is used | URL | https://www.ipcc.ch/2022/02/28/pr-wgii-ar6/ |
| custom: generatedBy | AI model which generated the asset | 21 characters | Dall-E |
Attaching More Metadata¶
If you have more metadata or provenance data that needs to be associated with the asset, you may create an IPFS metadata file and send the Cid in the integrityCid field. More metadata fields can be found on this page. You can also visit here to see the metadata example.
Action¶
An action, in the context of Numbers system, is the Cid or Nid (Numbers ID) that points to the profile of an action performed to an asset. By providing the right action, one can track and record all updares performed to an asset, providing transparency and accountability.
The default action of this API is action-commit, more pre-defined actions can be found here. You may also use nit to define your custom action.