Creation of fulfillments fails with insufficient rights error

Hi everyone,

currently, I try to migrate our fulfillment creation job from
the old REST API (fulfillments.json) to the new GraphQL API.

I created in my dev shop an order, which I marked as paid.
Now I’ll get the FulfillmentOrder and the corresponding OrderLineItem
via the following GraphQL Request.
URL: https://my-dev-shop.myshopify.com/admin/api/2025-01/graphql.json
Payload:

{
    orders(first: 1, query: "id:11974872990075") {
        nodes {
          id
          name
          fulfillmentOrders(first: 250) {
            nodes {
                id
                lineItems(first: 250) {
                    nodes {
                        id,
                        remainingQuantity
                    }
                }
            }
          }
        }
        pageInfo {
            hasNextPage
            endCursor
        }
    }
}

Response:

{
    "data": {
        "orders": {
            "nodes": [
                {
                    "id": "gid://shopify/Order/11974872990075",
                    "name": "#1027",
                    "fulfillmentOrders": {
                        "nodes": [
                            {
                                "id": "gid://shopify/FulfillmentOrder/12868499603835",
                                "lineItems": {
                                    "nodes": [
                                        {
                                            "id": "gid://shopify/FulfillmentOrderLineItem/35376656843131",
                                            "remainingQuantity": 1
                                        }
                                    ]
                                }
                            }
                        ]
                    }
                }
            ],
            "pageInfo": {
                "hasNextPage": false,
                "endCursor": "eyJsYXN0X2lkIjoxMTk3NDg3Mjk5MDA3NSwibGFzdF92YWx1ZSI6IjIwMjUtMDctMTcgMTM6MTU6NDAuNDU0ODk4In0="
            }
        }
    },
    "extensions": {
        "cost": {
            "requestedQueryCost": 159,
            "actualQueryCost": 9,
            "throttleStatus": {
                "maximumAvailable": 2000.0,
                "currentlyAvailable": 1991,
                "restoreRate": 100.0
            }
        }
    }
}

Now I got the IDs of the order and the orderline to create the mutation for the fulfillment as follows.
URL: https://my-dev-shop.myshopify.com/admin/api/2025-01/graphql.json
Payload:

{
    "query": "mutation fulfillmentCreate($fulfillment: FulfillmentInput!, $message: String) {  fulfillmentCreate(fulfillment: $fulfillment, message: $message) {    fulfillment {   status    }    userErrors {      field      message    }  }}",
    "variables": {
      "fulfillment": {
        "lineItemsByFulfillmentOrder": [
          {
            "fulfillmentOrderId": "gid://shopify/FulfillmentOrder/12868499603835",
            "fulfillmentOrderLineItems": [
                {
                    "id": "gid://shopify/FulfillmentOrderLineItem/35376656843131",
                    "quantity": 1
                }
            ]
        }],
        "notifyCustomer": false,
        "trackingInfo": {
          "number": "1234567890",
          "url": "https://tracking.example.com/1234567890",
          "company": "DHL"
        }
      },
      "message": "1"
    }
  }

Response:

{
    "data": {
        "fulfillmentCreate": {
            "fulfillment": null,
            "userErrors": [
                {
                    "field": [
                        "fulfillment"
                    ],
                    "message": "The api_client does not have access to the fulfillment order."
                }
            ]
        }
    },
    "extensions": {
        "cost": {
            "requestedQueryCost": 10,
            "actualQueryCost": 10,
            "throttleStatus": {
                "maximumAvailable": 2000.0,
                "currentlyAvailable": 1990,
                "restoreRate": 100.0
            }
        }
    }
}

Now I got an rights error, that the api_client does not have the necessary rights.
I tried the complete day to solve this issue. But I don’t get around the upper error.
As follows my current scopes of the api_client:
‘read_orders’,
‘read_all_orders’,
‘write_orders’,
‘read_merchant_managed_fulfillment_orders’,
‘write_merchant_managed_fulfillment_orders’,
‘write_third_party_fulfillment_orders’,
‘read_third_party_fulfillment_orders’,
‘read_customers’,
‘read_locations’,
‘read_products’,
‘read_discounts’,

The old rest api works without any issues with the same scopes. I tried to solve the issue
with the Shopify AI Assistant, but it keeps haluscinating, that I could send as payload “OrderID”,
but the documentation doesn’t show any option about that. Or the AI suggests to create a fulfillment
service, but this should be only made if we have other fulfillment services set.

Maybe you could help me?

Thank you very much!

1 Like

Hey @berti92 ,

It sounds like your app is an order management app, so your scopes should be fine. Can you check if the fulfillment order is currently available for your app to fulfil? To confirm, query the supportedActions field and make sure that CREATE_FULFILLMENT is an option for this order.

Let me know how that goes. If it keeps failing with CREATE_FULFILLMENT as an option, send the x-request-id from the response headers and I’ll see if I can find anything else out.

If CREATE_FULFILLMENT is not an option then the order may not be in a state that can be fulfilled or there may be other permissions errors blocking you here.

Some of this changed as of 2024-10, so if you were using the older version previously this may be part of it as well (although your scopes look fine to me so it doesn’t seem specific to the fulfillment scopes).

Hey @berti92, does the above help?

Hi @KyleG-Shopify, thank you very much for your fast response.

I checked the supportedActions. Sadly, the order doesnt support CREATE_FULFILLMENT.

Here the supportedActions as follows:

                                "supportedActions": [
                                    {
                                        "action": "REQUEST_FULFILLMENT"
                                    },
                                    {
                                        "action": "HOLD"
                                    }
                                ],

How do I get the necessary supportedAction?

I created the order in my Devshop and set it as paid. Do I need to do any other things to be able to fulfill this order?

Hey @berti92

Thanks for sharing that. In this case, you can either select request fulfillment on the order in the admin, or you can use the fulfillmentOrderSubmitFulfillmentRequest mutation.

That will put the order in a state to be fulfilled.

Hi @KyleG-Shopify,

I tried it via GraphQL:

Result from FullfillmentOrder-Query:

                                "id": "gid://shopify/FulfillmentOrder/12935339508091",
                                "supportedActions": [
                                    {
                                        "action": "REQUEST_FULFILLMENT"
                                    },
                                    {
                                        "action": "HOLD"
                                    }
                                ],

Now I try to set the order to be fulfilled via your mentioned Mutation:

GQL:
{
    "query": "mutation fulfillmentOrderSubmitFulfillmentRequest($id: ID!) {  fulfillmentOrderSubmitFulfillmentRequest(id: $id) {    originalFulfillmentOrder {      id      status      requestStatus    }    submittedFulfillmentOrder {      id      status      requestStatus    }    unsubmittedFulfillmentOrder {      id      status      requestStatus    }    userErrors {      field      message    }  }}",
    "variables": {
      "id": "gid://shopify/FulfillmentOrder/12935339508091"
    }
  }

Result:
{
    "data": {
        "fulfillmentOrderSubmitFulfillmentRequest": {
            "originalFulfillmentOrder": {
                "id": "gid://shopify/FulfillmentOrder/12935339508091",
                "status": "OPEN",
                "requestStatus": "SUBMITTED"
            },
            "submittedFulfillmentOrder": {
                "id": "gid://shopify/FulfillmentOrder/12935339508091",
                "status": "OPEN",
                "requestStatus": "SUBMITTED"
            },
            "unsubmittedFulfillmentOrder": null,
            "userErrors": []
        }
    },
}

Sadly, now I get the same scoping error as mentioned before.

If I check now the supported actions, I get the following:

                            {
                                "id": "gid://shopify/FulfillmentOrder/12935339508091",
                                "supportedActions": [
                                    {
                                        "action": "CANCEL_FULFILLMENT_ORDER"
                                    }
                                ],
                                "lineItems": {
                                    "nodes": [
                                        {
                                            "id": "gid://shopify/FulfillmentOrderLineItem/35376656843131",
                                            "remainingQuantity": 1
                                        }
                                    ]
                                }
                            }

I tried the same in the admin panel and the result is the same. The admin panel also only sets the supported action to “CANCEL_FULFILLMENT_ORDER”.

Did I something wrong?

Thanks again for your help!

Is the assigned location for this fulfillment order a 3rd party fulfillment location?

If so, this would be expected (as per the changelog linked above):

As of 2024-10 , the write_third_party_fulfillment_orders access scope permission will change for fulfillment creation. This access scope will no longer allow order management apps to fulfill fulfillment orders assigned to locations owned by other fulfillment service apps. Order management apps will still be able to access and manage these orders, only fulfillment creation will be prohibited.

Yes, that was the solution. I always used for test orders the “The 3p Fulfilled Snowboard” product. And this product had its own fulfillment location. Now everything works fine.

Thank you very much!

1 Like