Creating New Record using REST Api

I’m trying to simply create a new record using the REST Api. I’m a bit confused on why this is error out with code 400. I was wondering if someone could shed some light on this…

Here is a live jsfiddle to test with: https://jsfiddle.net/JokerMartini/ctwfpLvu/

If you need to access the actual shotgun page the page is
https://studiodashboard.shotgunstudio.com
user: admin
pw: redacted by mods

code:

function queryShotgun() {
    var headers = {
        'Content-Type': 'application/x-www-form-urlencoded',
        'Accept': 'application/json'
    };

    $.ajax({
        url: 'https://studiodashboard.shotgunstudio.com/api/v1/auth/access_token',
        method: 'post',

        headers: headers,
        data: {
            grant_type: 'client_credentials',
            client_id: 'queryToken',
            client_secret: '(redacted by mods'
        },
        success: function (data) {
            console.log(JSON.stringify(data));
            console.log(data);
            $('#accessOutput').html(data.access_token);

            var headers = {
            		'Accept':'application/json',
                'Content-Type': 'application/json',
                'Authorization': `Bearer ${data.access_token}`
            };
            var body = {
              'content': 'Here is information about the bug im encountering...', 
              'subject': 'Broken Tool',
              'sg_notetype': 'bug',
              'sg_priority': 'normal',
              'project': { 
              		"id": 93, 
                	"type": "Project"
                }, 
              'sg_status_list': 'opn',
              'note_links': [
              		{
                  	"id":1448, 
                  	"type": "Asset"
                  }]
            }

            $.ajax({
                url: 'https://studiodashboard.shotgunstudio.com/api/v1/entity/assets',
                method: 'post',
                data: JSON.stringify(body),
                headers: headers,
                success: function (data) {
                    console.log(JSON.stringify(data));
                    $('#queryOutput').val(JSON.stringify(data, null, 3));
                },
                error: err => {
                        console.log(err)
                    $('#queryOutput').value =  'Error:' + err;
                },
            })
        }
    })
}

window.onload = function(){
  queryShotgun();
};

Hey @JokerMartini,

It seems you are using field names of Task entity while posting to assets endpoint.
Inspecting the output of err object in the dev console gives:

"status":400,"code":103,"title":"API create() Asset.content doesn't exist."

basically its looking for the content field on Asset entity which does not exist.

3 Likes

Also, in case of direct calls to a REST API its considered best practice to first create a record using the basic attributes (non-relational), once the create operation is successful the response object of the post will give you a json containing the newly created object’s id.

Then a second patch or put (depends on the fields and situation) should be made to update relationships.

To summarize:

  • post to create entity
  • Retrieve newly created record id
  • update (put/patch) to detail endpoint ex: entity/<entity_id>, with relationship dictionary
  • Profit!

Please also be aware that the Shotgun REST API usually returns a json with attributes and relationships keys.

For ex, a Task dict might look like (I am just writing the below from memory):

{
id: 368,
type: "Task",
attributes: {
    content: "someName"
}
relationships: {
    project: {
        id: 214,
        code: "awesome",
        type: "Project"
    },
    entity: {
        id: 214,
        code: "assetover9000",
        type: "Asset"
    }
}
}

I am by no means an expert in the API, however these are some gotchas I encountered when interacting with the API.

Hope you find these useful.

3 Likes

I was struggling to find the response text. I just now saw it buried based on your comment. That helped resolve the ticket. You need a paypal link so i can thank you for your contributions.

1 Like

@Sreenathan_Nair how does one limit my result of Notes im collecting from shotgun though? I tried setting the limit param but that doesn’t appear to have any affect.

function queryShotgun() {
    var headers = {
        'Content-Type': 'application/x-www-form-urlencoded',
        'Accept': 'application/json'
    };

    $.ajax({
        url: 'https://studiodashboard.shotgunstudio.com/api/v1/auth/access_token',
        method: 'post',

        headers: headers,
        data: {
            grant_type: 'client_credentials',
            client_id: 'queryToken',
            client_secret: '(ooiqsnkvy6vsdJnehatxpdjd'
        },
        success: function (data) {
            console.log(JSON.stringify(data));
            console.log(data);
            $('#accessOutput').html(data.access_token);

            var headers = {
                'Content-Type': 'application/vnd+shotgun.api3_array+json',
                'Authorization': `Bearer ${data.access_token}`

            };
            var query = {
                    fields: ['subject', 'note_links', 'sg_status_list', 'content', 'updated_at'],
                    filters: [
                      ['project.Project.name', 'is', 'VFXP']
                    ],
                    sort: ['-updated_at'],
                    limit: 5
                };
						
            $.ajax({
            	url: 'https://studiodashboard.shotgunstudio.com/api/v1/entity/notes/_search',
                method: 'post',
                headers: headers,
                data: `${JSON.stringify(query)}`,
                success: function (data) {
                    console.log(JSON.stringify(data));
                    $('#queryOutput').val(JSON.stringify(data, null, 3));
                },
                error: err => {
                		console.log(err)
                    $('#queryOutput').value =  'Error:' + err;
                },
            })
        }
    })
}

window.onload = function(){
  queryShotgun();
};

No problem @JokerMartini, happy to help. I was also at one point in time trying to learn this “REST stuff” and can understand how overwhelming it can get. I will mention though that it is very bad practice to share any private information even for a testing site. I understand that you must be constrained for time, but I believe moving forward you should just be able to paste the error object with the sensitive information redacted and that should be enough to help anyone debug the issue with you.

4 Likes

For pagination I guess the following should work when posted to the _search endpoint:

{
     'page':{
        size: 25, 
        number: 1
    },
     ... other params
}

Where size is max number of records and number is the page number. This type of pagination is known as LimitOffsetPagination where the calculation is done after records are fetched.

So if you had 600 notes for example, you could run the query above to get 24 pages i.e 600 / 25 at which point you can increment the number from 1 till 24. Also note that there is a summarize option that one can make use to get the record count.

Please check this link for details about summarizing. I would suggest using summarize rather than querying the entire database to get back a record count.

Hope this helps, Good luck!

4 Likes

thanks again!

That solved it :slight_smile:
what do you do for work now/

1 Like

I’ve been a Pipeline TD most of my career :slight_smile: Though for the past few years I’ve ventured into more web services/front-end javascript type projects as well.

Looks to me like you are trying to build something along the lines of a frontend as well. If I could offer some unsolicited advice… I would drill-down and understand various specs for each of your components, there are many specifications out there:

The OpenAPI Specification
Google API Design Guidelines
Totally Awesome JSON API Spec

Please do bear in mind though that these are just some guidelines that can be followed (Like PEP8). Once you read and understand the ideologies of these specs, then a lot of the response JSON, API urls, Pagination strategies etc begin to make sense since most globally used REST APIs would adopt and follow some spec or the other.

Also, writing straight html with ajax calls might prove cumbersome for you in the long run. You should really look into ReactJS or Angular to use as the core UI framework for your project, just in case it decides to grow in size as projects tend to do,

I’m no expert on REST or JS or anything like that, just sharing some viewpoints I always keep in mind when starting on a new project.

Good luck to you and do feel free to reach out anytime.

4 Likes

Hi all! Just a heads up that I modified the original post to remove the password and client secret information. Please be mindful about sharing private authentication tokens (and other private data) on this public forum. Thanks!

2 Likes