GraphQL Filters Not Working in cURL POST Data

Dear GitLab Community,

I’m trying to collect some project related information using GitLab GraphQL API. The following query is working fine using the GraphiQL Explorer:

CASE A) Using GraphiQL UI


query {projects(search:"aggregatorr") {pageInfo{hasNextPage startCursor endCursor} nodes {id name fullPath}}}


  "data": {
    "projects": {
      "pageInfo": {
        "hasNextPage": false,
        "startCursor": "eyJpZCI6IjI1MTc5MDAwIn0",
        "endCursor": "eyJpZCI6IjI1MTc5MDAwIn0"
      "nodes": [
          "id": "gid://gitlab/Project/25179000",
          "name": "aggregatorr_",
          "fullPath": "quantum_api/gitlab/aggregatorr_"

But when I’m trying to do the same request using cURL it responds back with a 400 status code:

CASE B) Using cURL

  curl --verbose "" --header "Authorization: Bearer $GRAPHQL_TOKEN" --header "Content-Type: application/json" --request POST --data "{\"query\":\"query {projects(search:\"aggregatorr\") {pageInfo{hasNextPage startCursor endCursor} nodes {fullPath}}}\",\"variables\":null}" > $out_file

cURL Response (verbose, excerpt):


* Connection state changed (MAX_CONCURRENT_STREAMS == 256)!
} [130 bytes data]
* We are completely uploaded and fine
< HTTP/2 400 
< date: Tue, 04 May 2021 09:54:00 GMT
< content-type: text/html; charset=utf-8
< content-length: 0
< set-cookie: __cfduid=d34a1369d13e2aa782089fa371bab3e751620122039; expires=Thu, 03-Jun-21 09:53:59 GMT; path=/;; HttpOnly; SameSite=Lax; Secure
< x-request-id: 01F4VCRXJ8JBSJE9QDXHC5HVZP
< x-runtime: 0.127714
< gitlab-lb: fe-08-lb-gprd
< gitlab-sv: api-29-sv-gprd
< cf-cache-status: DYNAMIC
< cf-request-id: 09d8658dd900000d560e05f000000001
< expect-ct: max-age=604800, report-uri=""
< server: cloudflare
< cf-ray: 64a0d85c8e5f0d56-VIE
{ [0 bytes data]
100   130    0     0  100   130      0    218 --:--:-- --:--:-- --:--:--   218
* Connection #0 to host left intact
* Closing connection 0


So, either I do a mistake when passing the POST data or maybe the UI adds some necessary cookies/headers required for the filtering, what I would not why.

I also tried using @filename for the cURP POST data instead of escaped JSON and compared the passed data with the payload sent by the GraphiQL Explorer, they were the same.

When sending a cURL request without any filter like search: "test" or pagination, it just works fine, I’m getting a 200 status code and the response data, of course. It only does not work when passing filters.

Do you have any suggestions? Thanks a lot in advance. :slight_smile:

All the best,

I figured it out. When passing the data to the cURL using the --data-binary @"<data_file_path>" pointing to a stringified JSON, than it works:

JSON payload (e.g. /preproc/test.gql.json):

  "query": "query {projects(search:\"test\", first: 3) {pageInfo{hasNextPage, startCursor, endCursor}, nodes {fullPath}}}",
  "variables": null

cURL command:

curl --verbose "" --header "Authorization: Bearer $GRAPHQL_TOKEN" --header "Content-Type: application/json" --request POST --data-binary "@./preproc/test.gql.json"

Anyway, thanks for the reviews so far! :slight_smile: