Skip to content

Creating and Editing Assets

The Freeverse API is accessed via GraphQL. We recommend using a playground such as GraphQL Playground to create test queries and view the entire API documentation.


When you sign up for Freeverse, we will provide you with a url endpoint and universe ID with which you can access the API via GraphQL.

Packages & Code Examples

We provide NPM packages to easily create and sign mutations that modify your universe (Python packages to come soon). The source code for these packages can be found in our API Signer repository.

You can find several examples of how to use the API Signer library in our Examples repository.

Should you wish to build your own mutations for signing, the remainder of this page discusses the structure and format required. Please use this and the provided API Signer code as a reference.


Modifying your universe requires the use of a GraphQL mutation which requires three input parameters:

mutation ($opsString: JSON!, $signature: String!)
        input: { 
            ops: [$opsString], 
            signature: $signature,
            universe: your_universe_id,
  • ops: an string, in JSON format, with the modification operation that you wish to execute on your universe.
  • signature: the result of signing the operations string with your account.
  • universe: your universe id.


The mutation will fail if the passed signature does not match with that of the owner of the universe.

Ops string structure

The Ops string is a JSON structure with the following properties:

Property Values
type "create_asset"
msg JSON object. See message options below.

msg JSON properties

Property Values
nonce User's nonce for create_asset
Asset nonce for set_asset_props
id The ID of the asset (mandatory for set_asset_props)
owner_id The Freeverse ID of the asset owner (mandatory for create_asset)
props A string containing a JSON object with the public properties of this asset. See Asset Properties Standard for reference.
metadata A string containing JSON object with the private metadata of this asset

props JSON properties

The propsJSON object may contain any public property you wish to assign to your asset. We strongly advice to follow the standards as detailed in Asset Properties Standard.

metadata JSON properties

The metadata object is intended to store metadata about the asset, which will not be visible in public marketplaces. It is a JSON object which can store any properties and values that you desire.

NOnce values

All the users and assets within your universe are assigned a Number-Used-Once (NOnce) value. Any change you make to your universe must pass as a parameter the correct NOnce value, otherwise the mutation will fail.

  • create_asset operations require passing the user nonce. This can be obtained via querying the user.
  • set_asset_propsoperations require passing the asset nonce. This can be obtained by querying the asset.

Ops JSON example

Here is an example of a fully features ops JSON:

        "nonce": 1,
            "name": "Supercool Dragon",
            "description": "Legendary creature that loves fire.", 
            "image": "ipfs://QmPAg1mjxcEQPPtqsLoEcauVedaeMH81WXDPvPx3VC5zUz", 
            "attributes": [ 
                "trait_type": "Rarity", 
                "value": "Scarce"
                "trait_type": "Level", 
                "value": 5
                "trait_type": "Weight", 
                "value": 123.5
            "meta_field": "some meta data"


Note that the props and metadatafields are strings, not raw JSON objects!

Ops String example

The ops field must be passed as a string, and care must be taken to ensure whitespace and newlines are eliminated and quotation marks are escaped. The following code shows an example of how to inject all the fields into the ops string.

//input variables
const nonce = 1;
const user_id = "12345678901234567890"
const props = `"name": "Supercool Dragon", "description": "Legendary creature that loves fire.", "image": "ipfs://QmPAg1mjxcEQPPtqsLoEcauVedaeMH81WXDPvPx3VC5zUz", "attributes": [{"trait_type": "Rarity", "value": "Scarce"}, {"trait_type": "Level", "value": 5}, {"trait_type": "Weight", "value": 123.5}]`;
const metadata = `{"meta_field": "some meta data"}`;

//escape the quotation marks in props and metadata
const propsOps = props.replace(/"/g, `\\\"`);
const metadataOps = metadata.replace(/"/g, `\\\"`);

//insert all the variables to create ops string
//this is string ready to be signed
const opsString = `{"type":"create_asset","msg":{"nonce":${nonce},"owner_id":"${owner_id}","props":"${propsOps}","metadata":"${metadataOps}"}}`;

Signing the Ops String

The ops string must be signed by your account to prove that you have the correct permission to modify this universe. Full details can be found at Signing Ops String.

Building the GraphQL mutation

Once you have signed the ops string, you can include it in GraphQL mutation to send to Freeverse. To embed the ops string in the final mutation string, you will need to once again escape quotation marks and backslashes:

//remove the initial "0x" from the signature
const sigString = sig.signature.substring(2);

//add more escape characters to embed the ops string into the query
//this is necessary for correct graphQL parsing
const gqlOpsString = opsString.replace(/\\/g, `\\\\`).replace(/"/g, `\\\"`);

//create the final query by adding the ops string and the signature into the GQL
const createAssetMutation = `
mutation { 
    input: { 
        ops: ["${gqlOpsString}"], 
        signature: "${sigString}",
        universe: 0,

//send to freeverse and return result
const response = await fetch(api_address, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ 
    query: createAssetMutation
const resultJson = await response.json();

Mutation result

The result of signed input mutations is a JSON string which contains the new asset id:

  "data": {
    "execute": {
      "results": [