> For the complete documentation index, see [llms.txt](https://docs.kcc.io/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.kcc.io/developers/deploy-nfts/add-metadata.md).

# Add Metadata

<figure><img src="/files/q7M3R49Dah0PSsVK9lZ3" alt=""><figcaption></figcaption></figure>

Following the previous two tutorials, we created our contract and minted an NFT with ID = 1337. However, our minted NFT has no metadata associated with it. Without metadata, an NFT token is nothing but a token with an ID.&#x20;

Our smart contract implements the ERC721 meta extension, and it has the following method for getting the metadata URI of an NFT token:&#x20;

```solidity
    /// @notice A distinct Uniform Resource Identifier (URI) for a given asset.
    /// @dev Throws if `_tokenId` is not a valid NFT. URIs are defined in RFC
    ///  3986. The URI may point to a JSON file that conforms to the "ERC721
    ///  Metadata JSON Schema".
    function tokenURI(uint256 _tokenId) external view returns (string);
```

{% hint style="info" %}
The `tokenURI` method returns a string which is the URI to the metadata of an NFT token. And the metadata is presented in a JSON file.&#x20;
{% endhint %}

### Prepare Metadata&#x20;

The metadata of an NFT token is presented in a JSON file. Here is an example:&#x20;

```json
{
  "description": "My NFT", 
  "image": "https://example.com/1337.png", 
  "name": "Hacker's Token 1337",
  "attributes": [
    {
      "trait_type": "Mouth", 
      "value": "Surprised"
    }, 
    {
      "trait_type": "Level", 
      "value": 5
    }
  ]
}
```

{% hint style="info" %}

* `name` is the name of this item(i.e, this NFT token), because each NFT token may have a different name.&#x20;
* `image` is the link to the image of this NFT token.&#x20;
* `description` is a short description of this NFT token.&#x20;
* &#x20;and `attributes` is a list of attributes that this NFT token has.&#x20;

Apart from the commonly used fields in the above example,  some other fields are also supported in the metadata JSON file. You can find more [here](https://docs.opensea.io/docs/metadata-standards#metadata-structure).&#x20;
{% endhint %}

{% hint style="info" %}
Note the link to the image is also in the metadata JSON. In this example, we are using an ordinary (web2) link. However, to make it more decentralized, you can upload your images to IPFS and use the IPFS CIDs with a gateway.&#x20;
{% endhint %}

You should create one metadata JSON for each of your NFT tokens. Let's assume you are hosting  all the metadata JSON files on the host of `my-nft-metadata.com` , and the metadata JSON of each NFT token should have the following format:&#x20;

```
https://my-nft-metadata.com/1337
```

{% hint style="info" %}

* `https://my-nft-metadata.com` is called the base URI.
* &#x20;1337 is the ID of the NFT token&#x20;
  {% endhint %}

{% hint style="info" %}
If you upload all your metadata JSON files to IPFS, you should add the whole directory that includes all the JSON files.  Then, all the JSON files can be visited with the same base URI.  For example, [all the metadata JSON files of the BAYC collection share the same base URI](https://ipfs.io/ipfs/QmeSjSinHpPnmXmspMjwiXyN6zS4E9zccariGR3jxcaWtq).&#x20;
{% endhint %}

### Set The Base URI

After uploading all the metadata JSON files somewhere and hosting them with the same base URI, we can set the base URI of the contract. Again, we can use the `cast` command:&#x20;

```bash
FOUNDRY_PROFILE=kcc_testnet \
        cast send  --private-key=XXXXXXXXXX  \
        --legacy \
        0xd382De234f8d3B35823f1DB54C85cE6498a9DbC84c \
        'setBaseURI(string)' "https://my-nft-metadata.com/"
```

{% hint style="info" %}

* `XXXXXXXXX` is your private key as usual&#x20;
* `0xd382De234f8d3B353f1DB54C85cE6498a9DbC84c` is the address of our NFT contract.&#x20;
* And we use cast to call the `setBaseURI` method, and change the base URI to "<https://my-nft-metadata.com"&#x20>;
  {% endhint %}

Let's verify that our base URI  works as expected.  We use `cast` to get the `tokenURI` of the token of `1337`:&#x20;

```bash
FOUNDRY_PROFILE=kcc_testnet \
    cast call 0xd382De234f8d3B353f1DB54C85cE6498a9DbC84c \
    'tokenURI(uint256)(string)' 1337 
```

You should see the following URI printed out:&#x20;

```
https://my-nft-metadata.com/1337
```


---

# 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.kcc.io/developers/deploy-nfts/add-metadata.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.
