All Collections
Developers
Essential operations in the API
Essential operations in the API
Geora avatar
Written by Geora
Updated over a week ago

Create a new asset record

First, we can create a new asset record with the assetCreate mutation:

mutation {
assetCreate(
input: { class: "WHEAT", claims: [{ label: "Field", value: "West field" }] }
) {
id
}
}

Here, we are creating a new asset record labelled as a wheat record, with metadata attached (for now, only the field that the wheat was harvested from). If we run this mutation, we get back the data requested in the body of the mutation.

{
"data": {
"assetCreate": {
"id": "dXBkYXRlfDY5MGQ1MTM0LWQ3MzQtNGU0Yi1iN2ZiLWExNDY1MTFkY2Q0Yw=="
}
}
}

Checking update status

In Geora, creating and updating asset records is asynchronous. The blockchain takes a few seconds to process new transactions, so assetCreate returns an update ID which can be used to check the progress of the creation.

We can query the update like this:

{
update(id:"dXBkYXRlfDY5MGQ1MTM0LWQ3MzQtNGU0Yi1iN2ZiLWExNDY1MTFkY2Q0Yw==") {
id

result {
...on UpdateSuccess {
status

versionAfter {
id
asset {id}
class
claims {
edges {
node {
label
value
}
}
}
}
}

...on UpdateError {
status
error
}
}
}
}

The result field will return different data depending on the outcome of the creation. If successful, weve asked to see the new asset record (versionAfter), its class / asset type, and all the metadata we attached before.

{
"data": {
"update": {
"id": "dXBkYXRlfDY5MGQ1MTM0LWQ3MzQtNGU0Yi1iN2ZiLWExNDY1MTFkY2Q0Yw==",
"result": {
"status": "SUCCESS",
"versionAfter": {
"id": "YXNzZXRWZXJzaW9ufDUxNDg2",
"asset": {
"id": "YXNzZXR8MzYxOA=="
},
"class": "WHEAT",
"claims": {
"edges": [
{
"node": {
"label": "Field",
"value": "West field"
}
}
]
}
}
}
}
}
}

Since the update was successful, we have some new IDs we can use. The asset ID (YXNzZXR8MzYxOA==) refers to an asset record throughout its whole journey through the supply chain, while the asset version ID (YXNzZXRWZXJzaW9ufDUxNDg2) refers to a particular point in this history.

Adding more data to the asset

Over time, we want to add a lot more data to the asset. Metadata around a record is stored in Geora as claims: key-value pairs stating information about the record, which can optionally have files attached as evidence.

We can go ahead and add more data using assetUpdate, by providing the latest version ID of the asset record, and the claims we want to add.

mutation {
assetUpdate(
versionID: "YXNzZXRWZXJzaW9ufDUxNDg2"
input: {
claims: [
{ label: "grade", value: "APW1" }
{ label: "Farmer name", value: "Jane" }
]
}
) {
id
}
}


Alternatively, you could achieve the same thing using the assetPutClaims mutation, which is simpler when not editing anything else on the asset.

mutation {
assetPutClaims(
versionID: "YXNzZXRWZXJzaW9ufDUxNDg2"
input: [
{ label: "grade", value: "APW1" }
{ label: "Farmer name", value: "Jane" }
]
) {
id
}
}

Again, both of these mutations return an update ID. You can check the update status as before.

{
"data": {
"assetUpdate": {
"id": "dXBkYXRlfDlkNjllZmM1LWFhYjItNDc2Mi05YjE3LTI0N2ZjNzViYzgyZg=="
}
}
}

{
"data": {
"update": {
"id": "dXBkYXRlfDlkNjllZmM1LWFhYjItNDc2Mi05YjE3LTI0N2ZjNzViYzgyZg==",
"result": {
"status": "SUCCESS",
"versionAfter": {
"id": "YXNzZXRWZXJzaW9ufDUxNDg3",
"asset": {
"id": "YXNzZXR8MzYxOA=="
},
"class": "WHEAT",
"claims": {
"edges": [
{
"node": {
"label": "Farmer name",
"value": "Jane"
}
},
{
"node": {
"label": "Field",
"value": "West field"
}
},
{
"node": {
"label": "grade",
"value": "APW1"
}
}
]
}
}
}
}
}
}

If you add a claim with an existing label, its value will be replaced with the new value provided.

Adding images and files to an asset

To start adding evidence to your asset records claims, you can follow this process:

  1. Upload a file and obtain a file ID

  2. Add this file as many times as you want by including it as evidence for asset claims

Uploading files

Unfortunately, it is not yet possible to upload a file in the GraphQL playground. You can use curl or a client library in your language of choice to call the fileCreate mutation with your file attached, like:

curl "<https://api.geora.io/v2>" \\
-F operations='{"query":"mutation($file: Upload!) {fileCreate(file:$file) {id}}","variables":{"file":null}}' \\
-F map='{ "0": ["variables.file"] }' \\
-F 0=@'EarlyGrowth.jpg' \\
-H 'x-api-user: <API_USER>' \\
-H 'x-api-key: <API_KEY>' \\
-H 'x-geora-actor: <GEORA_ACTOR>'

This will return a file ID:

{"data":{"fileCreate":{"id":"ZmlsZXw5MjlmOGMwZS1mODc0LTQzYmEtYjFmNS1hOTIzNWU3N2ExMWM="}}}

Adding files as evidence

Using the file ID from above, you can add this as evidence with the optional evidence field:

mutation {
assetPutClaims(
versionID: "YXNzZXRWZXJzaW9ufDUxNDg3"
input: [
{
label: "Harvest Images"
value: "Attached"
evidence: ["ZmlsZXw5MjlmOGMwZS1mODc0LTQzYmEtYjFmNS1hOTIzNWU3N2ExMWM="]
}
]
) {
id
}
}

Viewing an asset

To query an asset record, use the assetVersion query for a single point in time, or the asset query for the full history.

Querying a single asset version

For example, to see all metadata attached to the record at its latest version:

{
assetVersion(id:"YXNzZXRWZXJzaW9ufDUxNDg4") {
id
class
claims {
edges {
node {
label
value
evidence {
edges {
node {
id
url
}
}
}
}
}
}
}
}

Here, we have requested all claims, their label and value, and the file ID and URL of all evidence attached to each claim.

{
"data": {
"assetVersion": {
"id": "YXNzZXRWZXJzaW9ufDUxNDg4",
"class": "WHEAT",
"claims": {
"edges": [
{
"node": {
"label": "Farmer name",
"value": "Jane",
"evidence": {
"edges": []
}
}
},
{
"node": {
"label": "Field",
"value": "West field",
"evidence": {
"edges": []
}
}
},
{
"node": {
"label": "grade",
"value": "APW1",
"evidence": {
"edges": []
}
}
},
{
"node": {
"label": "Harvest Images",
"value": "Attached",
"evidence": {
"edges": [
{
"node": {
"id": "ZmlsZXw5MjlmOGMwZS1mODc0LTQzYmEtYjFmNS1hOTIzNWU3N2ExMWM=",
"url": "<https://s3.ap-southeast-1.amazonaws.com/gap-geora-api-files-prod/929f8c0e-f874-43ba-b1f5-a9235e77a11c?AWSAccessKeyId=AKIA4XBH7X2UCRUAP4PF&Expires=1625786586&Signature=sMRPzQK5KM3eQkF9BLdLR9SPbzk%3D>"
}
}
]
}
}
}
]
}
}
}
}

The url field on files can be used to view the file. Note that the generated URL is time-limited to 10 minutes, after which you will need to query again to get a new URL. This ensures that permission changes to files will be respected.

Querying the asset record history

To see the history of an asset, query using asset with the asset ID (not the asset version ID). In this query, we ask for the claims on all past versions of the asset (in reverse chronological order). We also ask for details on all updates that have been made to the asset: what the update was, when it was submitted, and who submitted it:

{
asset(id: "YXNzZXR8MzYxOA==") {
versions {
edges {
node {
claims {
edges {
node {
label
value
}
}
}
}
}
}

latestVersion {
updates {
edges {
node {
id
change
submittedBy {
name
}
submittedAt
}
}
}
}
}
}

The return data looks like:

{
"data": {
"asset": {
"versions": {
"edges": [
{
"node": {
"claims": {
"edges": [
{
"node": {
"label": "Farmer name",
"value": "Jane"
}
},
{
"node": {
"label": "Field",
"value": "West field"
}
},
{
"node": {
"label": "grade",
"value": "APW1"
}
},
{
"node": {
"label": "Harvest Images",
"value": "Attached"
}
}
]
}
}
},
{
"node": {
"claims": {
"edges": [
{
"node": {
"label": "Farmer name",
"value": "Jane"
}
},
{
"node": {
"label": "Field",
"value": "West field"
}
},
{
"node": {
"label": "grade",
"value": "APW1"
}
}
]
}
}
},
{
"node": {
"claims": {
"edges": [
{
"node": {
"label": "Field",
"value": "West field"
}
}
]
}
}
}
]
},
"latestVersion": {
"updates": {
"edges": [
{
"node": {
"id": "dXBkYXRlfGVlM2E3YzNlLWQwYzYtNGI2MS1hYTc1LTA2YzA3NjE4ZjljZA==",
"change": "{\\"claims\\": [{\\"label\\": \\"Harvest Images\\", \\"value\\": \\"Attached\\", \\"evidence\\": [\\"929f8c0e-f874-43ba-b1f5-a9235e77a11c\\"]}], \\"currentAssetID\\": 3618, \\"actorRelationships\\": []}",
"submittedBy": {
"name": "Australian Certified Organic"
},
"submittedAt": "2021-07-08T23:11:39.210Z"
}
},
{
"node": {
"id": "dXBkYXRlfDlkNjllZmM1LWFhYjItNDc2Mi05YjE3LTI0N2ZjNzViYzgyZg==",
"change": "{\\"claims\\": [{\\"label\\": \\"grade\\", \\"value\\": \\"APW1\\", \\"evidence\\": []}, {\\"label\\": \\"Farmer name\\", \\"value\\": \\"Jane\\", \\"evidence\\": []}], \\"currentAssetID\\": 3618, \\"actorRelationships\\": []}",
"submittedBy": {
"name": "Australian Certified Organic"
},
"submittedAt": "2021-07-08T23:02:29.705Z"
}
},
{
"node": {
"id": "dXBkYXRlfDY5MGQ1MTM0LWQ3MzQtNGU0Yi1iN2ZiLWExNDY1MTFkY2Q0Yw==",
"change": "{\\"class\\": \\"WHEAT\\", \\"claims\\": [{\\"label\\": \\"Field\\", \\"value\\": \\"West field\\", \\"evidence\\": []}], \\"currentAssetID\\": 3618, \\"actorRelationships\\": [{\\"actorID\\": \\"1b354011-ecc9-4cfc-a44b-b2ff838a9561\\", \\"isManager\\": true, \\"isCustodian\\": true, \\"contractAddress\\": \\"798fF1115421F781E6872cA45F3e97B519E1a71C\\", \\"permissionsGranted\\": [], \\"exactOwnershipPercentage\\": \\"1\\"}]}",
"submittedBy": {
"name": "Australian Certified Organic"
},
"submittedAt": "2021-07-08T22:53:48.923Z"
}
}
]
}
}
}
}
}

Need a hand? πŸ€”

Get in touch using the live chat button to the bottom right of any Geora page and you'll be connected to us in real time! πŸ‘‰

Did this answer your question?