# How to find elements in a workspace

**URL:** <https://community.bluescape.com/t/how-to-find-elements-in-a-workspace/2134>\
**Category:** Developer\
**Tags:** api\
**Created:** [July 26, 2022, 6:48pm UTC](https://community.bluescape.com/t/how-to-find-elements-in-a-workspace/2134 "2022-07-26T18:48:58Z")\
**Posts on this page:** 1\
**Page:** 1

<div class="post-metadata">

**Author:** ![Tom\_Garrett](https://avatars.discourse-cdn.com/v4/letter/t/258eb7/32.png) [@Tom\_Garrett](https://community.bluescape.com/u/Tom_Garrett)\
**Post date:** [July 26, 2022, 6:48pm UTC](https://community.bluescape.com/t/how-to-find-elements-in-a-workspace/2134/1 "2022-07-26T18:48:58Z")

</div>

**Objective** : find elements in the workspace that match a specific text string. This is done to get properties of that element, to edit it or to delete it. Also, you may want to find a specific canvas to retrieve its content or to add more elements to it. In this page we will search for a specific Canvas for its name and will display the content of that Canvas.

This page contains the implementation details for [v3 REST APIs](https://community.bluescape.com/t/how-to-find-elements-in-a-workspace/2134#implementation-using-rest-apis-1) and for [v3 GraphQL APIs](https://community.bluescape.com/t/how-to-find-elements-in-a-workspace/2134#implementation-using-graphql-apis-4).

## Implementation using REST APIs

In v3 we have access to a `search` API. This API allows to run a search for a string and we will get all the objects matching that string in their text content.

| **Endpoint** | /v3/workspaces/\<workspaceId\>/search |
| --- | --- |
| **Method** | POST |
| **Comments** | Searches a workspace with a query string, can filter by element types. |

**IMPORTANT** : currently this search API does not match or search the content of Comments in elements.  
The output contains a “matchText” field that shows what is the text matching the search query.

| Endpoint | /v3/workspaces/\<workspaceId\>/elements?canvas=\<CANVAS\_ID\> |
| --- | --- |
| Method | GET |
| Comments | Returns the content of the Canvas specified by \<CANVAS\_ID\> |

You can specify what type of elements are included in the search. If you want to search only on Image, Shape and Text elements, you can specify the `"filterTypes"` field with those values, as in this example of the request body:

```auto
{
  "filterTypes": [
    "Image", "Shape", "Text"
  ],
  "orderDirection": "desc",
  "query": "<STRING_TO_MATCH>"
}

```

If you want to run a search for all the elements in the workspace, and not for a specific set, then simply remove the “filterTypes” key in the body request of the API call.

```auto
{
  "orderDirection": "desc",
  "query": "<STRING_TO_MATCH>" 
}

```

Below there is an example of the response body of this API. The search was for “January 2021”, for Canvas elements. The output contains 2 results.

- The `"matchText"` field shows the text that matched the search query.
- The `"element"` key contains the properties of each matched element.
- The values for the `"id"` fields are only examples, they will be different in your workspace.

This is an example of the results (response body) for a search for for “January 2021”:

```auto
{
    "data": [
        {
            "matchText": "January 2021 reports: summary data",
            "score": 0.046,
            "element": {
                "id": "5ef27790ff5317444e00052a",
                "zIndex": 1330,
                "transform": {
                    "x": 115610.49999999997,
                    "y": -33618,
                    "scaleX": 1,
                    "scaleY": 1
                },
                "pinned": false,
                "comments": [],
                "type": "Canvas",
                "name": "January 2021 reports: summary data",
                "style": {
                    "width": 47914,
                    "height": 25208,
                    "borderColor": {
                        "r": 238, "g": 85, "b": 80, "a": 1
                    }
                }
            }
        },
        {
            "matchText": "January 2021: all projects",
            "score": 0.032,
            "element": {
                "id": "617c44b4b9575c0c10e783c9",
                "zIndex": 2963,
                "transform": {
                    "x": 60092,
                    "y": -34409,
                    "scaleX": 1,
                    "scaleY": 1
                },
                "pinned": false,
                "comments": [],
                "type": "Canvas",
                "name": "January 2021: all projects",
                "style": {
                    "width": 43243,
                    "height": 20170,
                    "borderColor": {
                        "r": 153, "g": 198, "b": 255, "a": 1
                    }
                }
            }
        }
    ]
}

```

Now you can process the results or run a new search with a search query with more specific terms, for example “January 2021 summary data”.

## Code sample

See below code samples for a search on a Canvas (by name), to list the content of that Canvas.

We will run a search for the name, restricted to Canvas type (see the `"filterTypes"` field in the request body). For these examples we are assuming that there will be a Canvas that has the name we are trying to match with the search query.

> **cURL**
>
> ```auto
> curl --location --request POST 'https://api.apps.us.bluescape.com/v3/workspaces/&lt;workspaceId&gt;/search' \
> --header 'Authorization: Bearer <SET_TOKEN>' \
> --data-raw '{
> "filterTypes": [
> "Canvas"
> ],
> "orderDirection": "desc",
> "query": "<STRING_TO_MATCH>"
> }'
> # if you want to get a shorter version of the results of the search, add the following line at to the script above, after "}'":
> # | jq . | egrep "(matchText|\"id\"|type)" 
> 
> ```

> **Node.js**
>
> ```auto
> // Node.js Javascript REST API example for search and list content of Canvas
> /*
> 
> How to run:
> node this_script_name.js
> 
> Requires "axios" module (0.19.0), run:
> npm install axios
> 
> website: https://github.com/axios/axios
> 
> */
> 
> var axios = require('axios');
> 
> const token = '<SET_TOKEN>';
> const portal = 'https://api.apps.us.bluescape.com';
> const workspaceId = '<SET_WORKSPACE_ID>';
> const api_version = 'v3';
> 
> function runRequest(portal, api_version, api_endpoint, the_method, data_load) {
> var request_values = {
> url: `${portal}/${api_version}${api_endpoint}`,
> method: the_method,
> headers: {
> 'Content-Type': 'application/json',
> 'Authorization': "Bearer " + token
> },
> data: data_load,
> };
> 
> let req = axios(request_values)
> .catch(error => {
> console.error(`ERROR processing ${portal}/${api_version}${api_endpoint}`);
> console.error(error.message);
> console.error(error.response.data);
> return Promise.reject(error);
> });;
> 
> return req;
> }
> 
> async function runSearchAndGetCanvasContent() {
> try {
> 
> // Run search
> // Path: /v3/workspaces//search
>         
> const canvasNameToMatch = '<STRING_TO_MATCH>';
> 
> var api_endpoint = `/workspaces/${workspaceId}/search`;
> var the_method = 'POST';
> 
> var data_load = {
> "filterTypes": [
> "Canvas"
> ],
> "orderDirection": "desc",
> "query": canvasNameToMatch
> }
> 
> var canvasSearchResponse = await runRequest(portal, api_version, api_endpoint, the_method, data_load);
> const canvasList = canvasSearchResponse.data.data;
> console.log("Search results:");
> console.log(canvasList);
> 
> var canvasID = '';
> 
> for (var i in canvasList) {
> theCanvasName = canvasList[i].element.name;
> console.log("theCanvasName:", theCanvasName)
> if (theCanvasName == canvasNameToMatch) {
> canvasID = canvasList[i].element.id
> break
> }
> }
> 
> // Let's get the content of the Canvas
> api_endpoint = `/workspaces/${workspaceId}/elements?canvas=${canvasID}`;
> the_method = 'GET';
> data_load = '';
> 
> var listOfCanvasContent = await runRequest(portal, api_version, api_endpoint, the_method, data_load);
> const canvasContent = listOfCanvasContent.data.data; // It is an array of elements data
> console.log("Canvas Content:", canvasContent); 
> 
> } catch (error) {
> console.error('ERROR:');
> console.error(error.message);
> }
> }
> 
> // Run the requests
> runSearchAndGetCanvasContent(); 
> 
> ```

> **Python**
>
> ```auto
> # Python Code (python 3.5+)
> import requests
> import datetime
> import pprint
> 
> '''
> 
> Required modules:
> requests 2.22.0
> 
> '''
> 
> token = ''
> 
> if __name__ == " __main__":
> portal = 'https://api.apps.us.bluescape.com'
> workspaceId = '<SET_WORKSPACE_ID>' # REMEMBER TO ADD THE WORKSPACE ID
> 
> canvasNameToMatch = '<STRING_TO_MATCH>'
> 
> # Run search
> # Path: /v3/workspaces//search
> 
> API_endpoint = '/v3/workspaces/' + workspaceId + '/search'
> 
> data_load = {
> "filterTypes": [
> "Canvas"
> ],
> "orderDirection": "desc",
> "query": canvasNameToMatch
> }
> 
> the_request = requests.post(
> portal + API_endpoint,
> headers={"Authorization": "Bearer " + token,
> "Content-Type": "application/json"
> },
> json=data_load
> )
> 
> canvasSearchResponse = the_request.json()
> # pprint.pprint(canvasSearchResponse) # uncomment to see the list
> 
> canvasList = canvasSearchResponse['data']
> print("Search results:")
> pprint.pprint(canvasList)
> 
> canvasID = ''
> 
> for theElement in canvasList:
> print(theElement)
> theCanvasName = theElement['element']['name']
> if theCanvasName == canvasNameToMatch:
> canvasID = theElement['element']['id']
> 
> # Let's get the content from the canvas
> API_endpoint = '/v3/workspaces/' + workspaceId + '/elements?canvas=' + canvasID
> 
> the_request = requests.get(
> portal + API_endpoint,
> headers={"Authorization": "Bearer " + token,
> "Content-Type": "application/json"
> }
> )
> 
> listOfCanvasContent = the_request.json()
> # You can process this list of arrays of elements data
> canvasContent = listOfCanvasContent['data']
> print("Canvas content:")
> pprint.pprint(listOfCanvasContent) 
> 
> ```

## OUTPUT

The scripts above will show 2 sets of outputs:

- The results of the search
- The content of the Canvas that matches the search query

Search Results output (values for `"id"`are samples only, they will be different for your workspace):

```auto
{
  "data": [
    {
      "matchText": "January 2021 meeting",
      "score": 0.04,
      "element": {
        "comments": [],
        "id": "618186ede12c4366912c6d18",
        "name": "January 2021 meeting",
        "pinned": false,
        "style": {
          "borderColor": {
            "a": 1, "b": 255, "g": 198, "r": 153
          },
          "height": 2419, "width": 2159
        },
        "transform": {
          "scaleX": 1, "scaleY": 1, "x": -1976, "y": 2972
        },
        "type": "Canvas",
        "zIndex": 3751
      }
    }
  ]
}

```

Canvas Content output (values for `"id"` and `"url"` are samples only, they will be different for your workspace):

```auto
{
  "data": [
    {
      "asset": {
        "documentFormat": "pdf",
        "url": "https://s3.us-east-1.amazonaws.com/acceptance-new.public-assets.bluescape.com/sessions/objects/E-IYMCBISe7QIPlxanns/61819fbdaf0a7a58abdf4ae9.pdf?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=AKIAIVWWSYKG7DKFMQJA%2F20211103%2Fus-east-1%2Fs3%2Faws4_request&X-Amz-Date=20211103T232428Z&X-Amz-Expires=300&X-Amz-Signature=bb7f45deefb4cea22c1f09d8f8d18d671febc123ce1acf74dda8e882abfd170c&X-Amz-SignedHeaders=host"
      },
      "attachments": [],
      "comments": [],
      "filename": "New_CICD_Process_slim-21-pages.pdf",
      "height": 720,
      "id": "61819fbdaf0a7a58abdf4ae9",
      "ingestionState": "complete_success",
      "pinned": false,
      "preview": {
        "imageFormat": "jpeg",
        "url": "https://s3.us-east-1.amazonaws.com/acceptance-new.public-assets.bluescape.com/sessions/objects/E-IYMCBISe7QIPlxanns/61819fbdaf0a7a58abdf4ae9.pdf_thumb.jpg?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=AKIAIVWWSYKG7DKFMQJA%2F20211103%2Fus-east-1%2Fs3%2Faws4_request&X-Amz-Date=20211103T232428Z&X-Amz-Expires=300&X-Amz-Signature=d423bfdc3443d1a16fee63209de4564c55c767ab1dea51656228be8dd9d6b712&X-Amz-SignedHeaders=host"
      },
      "title": "New_CICD_Process_slim-21-pages.pdf",
      "transform": {
        "scaleX": 0.78125, "scaleY": 0.7819444444444444, "x": -1784, "y": 3451
      },
      "type": "Document",
      "width": 1280,
      "zIndex": 3758
    },
    {
      "blocks": [
        {
          "align": "left",
          "content": [
            {
              "text": "Description: documents for the January 2021 meeting"
            }
          ],
          "type": "TextBlock"
        }
      ],
      "comments": [],
      "id": "61819feaaf0a7a58abdf4aeb",
      "pinned": false,
      "style": {
        ...
        ...
      },
      "text": "Description: documents for the January 2021 meeting",
      "transform": {
        "scaleX": 1, "scaleY": 1, "x": -1784, "y": 3200
      },
      "type": "Text",
      "zIndex": 3759
    },
    ...
    ...
    {
      "asset": {
        "imageFormat": "jpeg",
        "url": "https://s3.us-east-1.amazonaws.com/acceptance-new.public-assets.bluescape.com/sessions/objects/E-IYMCBISe7QIPlxanns/6181a214af0a7a58abdf4af9.jpg?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=AKIAIVWWSYKG7DKFMQJA%2F20211103%2Fus-east-1%2Fs3%2Faws4_request&X-Amz-Date=20211103T232428Z&X-Amz-Expires=300&X-Amz-Signature=ea7f72b657acb4ac40efe61209d93e75479370766e8261b60a2d23cf1742f7bc&X-Amz-SignedHeaders=host"
      },
      "attachments": [],
      "comments": [],
      "filename": "Compliance reviewer.jpg",
      "height": 1920,
      "id": "6181a214af0a7a58abdf4af9",
      "ingestionState": "complete_success",
      "pinned": false,
      "title": "Compliance reviewer.jpg",
      "transform": {
        "scaleX": 0.5208333333333334, "scaleY": 0.5208333333333334, "x": -1784, "y": 4144
      },
      "type": "Image",
      "width": 1920,
      "zIndex": 3763
    },
    {
      "blocks": [
        {
          "align": "left",
          "content": [
            {
              "text": "Compliance Department person"
            }
          ],
          "type": "TextBlock"
        }
      ],
      "comments": [],
      "id": "6181a50caf0a7a58abdf4afd",
      "pinned": false,
      "style": {
        ...
        ...
      },
      "text": "Compliance Department person",
      "transform": {
        "scaleX": 1, "scaleY": 1, "x": -1153, "y": 5132
      },
      "type": "Text",
      "zIndex": 3764
    }
  ]
}

```

## Implementation using GraphQL APIs

In GraphQl we currently do not have a search API. The approach here is to run a query for the type of element you want, and then loop through the list of results looking for the specific element matching the string you are after.

> **cURL**
>
> ```auto
> # Uses 'jq' to filter the results, to filter the string to match: | jq '.data.elements[] | select(.name|test("<STRING_TO_MATCH>"))'
> curl --location --request POST 'https://api.apps.us.bluescape.com/v3/graphql' \
> --header 'Authorization: Bearer <SET_TOKEN>' \
> --header 'Content-Type: application/json' \
> --data-raw '{"query":"query getCanvasesfromWorkspace($workspaceId: String!) {\n elements(workspaceId: $workspaceId, type: Canvas) {\n ... on Canvas {\n type: __typename\n id\n name\n transform {\n x\n y\n } \n }\n } \n}","variables":{"workspaceId":"<workspaceId>"}}' | jq '.data.elements[] | select(.name|test("<STRING_TO_MATCH>"))'
> 
> ```

> **Node.js**
>
> ```auto
> // Node.js Javascript
> // List the content of a canvas searching for a match for canvas "name" in list of canvases from the workspace
> 
> /*
> 
> How to run:
> node this_script_name.js
> 
> Requires "axios" module (0.19.0), run:
> npm install axios
> 
> website: https://github.com/axios/axios
> 
> */
> 
> const axios = require('axios');
> 
> const url = "https://api.apps.us.bluescape.com/v3/graphql"
> const token = "<SET_TOKEN>"
> const workspaceId = "<workspaceId>"
> // String to match on the Canvas "name" field
> const canvasNameToMatch = 'January 2021 meeting'
> 
> const makeQuery = async (query, params) => {
> try {
> const response = await axios.post(url,
> {
> query: query,
> variables: params
> },
> {
> headers: { "Authorization": "Bearer " + token }
> })
> return response.data
> }
> catch (error) {
> console.error(error)
> }
> }
> 
> async function getCanvasContentFoundByName() {
> 
> const canvasListQuery =
> `query getCanvasesfromWorkspace($workspaceId: String!) {
> elements(workspaceId: $workspaceId, type: Canvas) {
> ... on Canvas {
> type: __typename
> id
> name
> transform {
> x
> y
> }      
> }
> }    
> }`
> 
> const canvasListParams = {
> "workspaceId": workspaceId
> }
> const canvasResponse = await makeQuery(canvasListQuery, canvasListParams);
> const canvasList = canvasResponse.data.elements;
> console.log("Canvases List:");
> console.log(canvasList);
> 
> var canvasID = ''
> 
> // Search for the match in the "name" field
> for (var i in canvasList) {
> theCanvasName = canvasList[i].name;
> if (theCanvasName == canvasNameToMatch) {
> canvasID = canvasList[i].id
> break
> }
> }
> 
> const getCanvasContentQuery =
> `query getCanvasContent($workspaceId: String!, $canvasId: String!) {
> elements(workspaceId: $workspaceId, canvasId: $canvasId ) {            
> type: __typename
> id            
> transform {
> x
> y
> }     
> ...on Image {
> title
> filename
> asset { imageFormat }
> } 
> ... on Text {
> text
> }
> ... on Document {
> title
> filename
> asset { documentFormat }
> }
>           
> }    
> }`
> 
> const textParamsGetCanvasContent = {
> "workspaceId": workspaceId,
> "canvasId": canvasID
> }
> 
> const textResponse = await makeQuery(getCanvasContentQuery, textParamsGetCanvasContent);
> const listOfCanvasContent = textResponse.data.elements; // Process this list as needed 
> console.log("Canvas Content:");
> console.log(listOfCanvasContent);
> }
> 
> // Run the requests
> getCanvasContentFoundByName();
> 
> ```

> **Python**
>
> ```auto
> import requests
> import pprint
> 
> # List the content of a canvas searching for a match for canvas "name" in list of canvases from the workspace
> 
> '''
> Required modules:
> requests 2.22.0
> '''
> 
> url = "https://api.apps.us.bluescape.com/v3/graphql"
> token = "<SET_TOKEN>"
> workspaceId = "<workspaceId>"
> 
> # String to match on the Canvas "name" field
> canvasNameToMatch = '<STRING_TO_MATCH>'
> 
> getCanvasesQuery = """
> query getCanvasesfromWorkspace($workspaceId: String!) {
> elements(workspaceId: $workspaceId, type: Canvas) {
> ... on Canvas {
> type: __typename
> id
> name
> transform {
> x
> y
> }      
> }
> }    
> }
> """
> 
> getCanvasContentQuery = """
> query getCanvasContent($workspaceId: String!, $canvasId: String!) {
> elements(workspaceId: $workspaceId, canvasId: $canvasId ) {            
> type: __typename
> id            
> transform {
> x
> y
> }     
> ...on Image {
> title
> filename
> asset { imageFormat }
> } 
> ... on Text {
> text
> }
> ... on Document {
> title
> filename
> asset { documentFormat }
> }
>             
> }    
> }
> """
> 
> variables = {
> "workspaceId": workspaceId
> }
> 
> def makePostQuery(query, variables):
> response = requests.post(url,
> headers={"Authorization": "Bearer " + token
> },
> json={
> 'query': query,
> 'variables': variables
> })
> return response.json()
> 
> if __name__ == " __main__":
> response = makePostQuery(getCanvasesQuery, variables)
> listOfCanvases = response['data']['elements']
> 
> print("List of Canvases:")
> pprint.pprint(listOfCanvases)
> 
> for canvasItem in listOfCanvases:
> if canvasItem['name'] == canvasNameToMatch:
> # Get the content of the matching Canvas
> variablesLocal = {
> "workspaceId": workspaceId,
> "canvasId": canvasItem['id']
> }
> CanvasContent = makePostQuery(
> getCanvasContentQuery, variablesLocal)                
> listOfCanvasContent = CanvasContent['data']['elements'] # Process this list as needed            
> print("Canvas content:")
> pprint.pprint(ListCanvasContent) # uncomment to see the list 
> break # leave the loop
> 
> ```

## OUTPUT

The scripts above (that use GraphQL) will show 2 sets of outputs:

- The results of the search
- The content of the Canvas that matches the search query

Search Results output (values for `"id"` are samples only, they will be different for your workspace):

```auto
[
  {
    "type": "Canvas",
    "id": "60c40b72736f01e805f71b54",
    "name": "FEBRUARY 2021",
    "transform": {
      "x": -11461,
      "y": 11650
    }
  },
  {
    "type": "Canvas",
    "id": "618186ede12c4366912c6d18",
    "name": "January 2021 meeting",
    "transform": {
      "x": -1976,
      "y": 2972
    }
  },
  {
    "type": "Canvas",
    "id": "6182f80c0dab0b47b057decf",
    "name": "COMPLIANCE MATRIX",
    "transform": {
      "x": 0,
      "y": 0
    }
  },
  ...
  ...
  {
    "type": "Canvas",
    "id": "6182f84c0dff0b47b057dea6",
    "name": "Notes for next meeting",
    "transform": {
      "x": 0,
      "y": 0
    }
  }
]

```

Canvas Content output (values for `"id"` are samples only, they will be different for your workspace):

```auto
[
  {
    "type": "Document",
    "id": "61819fbdaf0a7a58abdf4ae9",
    "transform": {
      "x": -1784,
      "y": 3451
    },
    "title": "New_CICD_Process_slim-21-pages.pdf",
    "filename": "New_CICD_Process_slim-21-pages.pdf",
    "asset": {
      "documentFormat": "pdf"
    }
  },
  {
    "type": "Text",
    "id": "61819feaaf0a7a58abdf4aeb",
    "transform": {
      "x": -1784,
      "y": 3200
    },
    "text": "Description: documents for the January 2021 meeting"
  },
  {
    "type": "Image",
    "id": "6181a214af0a7a58abdf4af9",
    "transform": {
      "x": -1784,
      "y": 4144
    },
    "title": "Compliance reviewer.jpg",
    "filename": "Compliance reviewer.jpg",
    "asset": {
      "imageFormat": "jpeg"
    }
  },
  {
    "type": "Text",
    "id": "6181a50caf0a7a58abdf4afd",
    "transform": {
      "x": -1153,
      "y": 5132
    },
    "text": "Compliance Department person"
  }
]

```

 

> # Where to Next?
> 
> - [How to use the findAvailableArea API in v3](https://community.bluescape.com/t/how-to-use-the-findavailablearea-api-in-v3/2135)
> - [Bluescape API Guides](https://community.bluescape.com/t/bluescape-api-guides-landing-page/2020)
> - [Bluescape API Overview](https://community.bluescape.com/t/wip-bluescape-api-overview/2021/2)
> - [Latest Developer topics](https://community.bluescape.com/c/developer/14)
> 
> **Not what you were looking for? Reply below or [Search](https://community.bluescape.com/search) the community and discover more Bluescape.**
