SproutGigs' API Documentation

Last updated at Jul 23, 2026

Contents

Overview

The SproutGigs API is a JSON-based API for managing your account programmatically. Buyers can post and manage jobs end-to-end — including targeting, ratings, and freelancer lists — and register webhooks to be notified of job status changes and task submissions instead of polling. There's also a read-only API for Gigs, covering categories, listings, reviews, and seller Q&A.

The base endpoint for all requests is https://sproutgigs.com/api/

If you have deposited over $1,000 in crypto, please message support for auto-approval on your posts. Others are considered on a case-by-case basis.

Authentication

Every API request needs to be authenticated. You can generate a new API secret from the Settings tab of your Account Settings page — doing so invalidates the previous one immediately, with no grace period, so update it in your own systems atomically with the regenerate action rather than rolling it out gradually.

To sign requests, add the header Authorization with the value of 'Basic ' + the base 64 encoding of your USER_ID and API_SECRET separated by colon

Example:

1. Generate the base64 encoding of your user_id and api_secret

        php> echo base64_encode('user_id:api_secret');
        php> dXNlcl9pZDphcGlfc2VjcmV0
      

2. Send the header Authorization in the request

        $ curl -H 'Authorization: Basic dXNlcl9pZDphcGlfc2VjcmV0' \
        https://sproutgigs.com/api/jobs/get-zones.php
      

Rate Limit

The API is limited to 1 request per second. Going over that returns a 429 HTTP status — if you hit it, wait 10 seconds before sending requests again.

Errors

Almost every response — success or failure — comes back with an HTTP 200 status; the 429 from Rate Limit is the one exception. This means checking the HTTP status code isn't enough — always check the ok field in the response body instead. When ok is false, a human-readable explanation is included under message. On batch endpoints like Rate Multiple Tasks, where each item in the response can succeed or fail independently, that same message field is included per item instead of once for the whole request. A malformed JSON request body returns {"ok": false, "message": "Invalid JSON body."}.

Blocked account: a blocked account returns {"ok": false, "message": "Your account is blocked. Please contact support."} instead of the generic Unauthorized — this happens once your api_secret is confirmed correct but the account itself has been blocked.

Identity verification (KYC): almost every job-management endpoint — Post Job, Add Positions, Edit Targeting, Feature Job, Pause Job, Resume Job, Restart Job, Stop Job, Set Speed, Set TTR, Set Daily Tasks Limit, Set Hourly Tasks Limit, and Set Distribution — will reject every request with ok: false if your account has a pending identity-verification request. It means an admin asked for more identity info and 14 days passed without a response. Go to Account Settings > Identity/KYC to submit what's requested and clear it yourself — there's no need to contact support. Read-only endpoints (the get-* ones) are never affected. There's currently no way to check this status ahead of time via the API — you'll only find out by hitting the block on an actual request.

Account restrictions: some accounts are restricted from running jobs — either by our team, or automatically when signals suggest fraud (e.g. multiple accounts sharing the same source). If a job-management call fails with "You cannot run jobs. Please contact support.", this is why. There's currently no way to check this status ahead of time via the API.

Terms

Shorthand used throughout this doc:

  • TTR (Time to Rate) — the deadline, in days, a buyer has to rate a submitted task before it's automatically rated OK. Set via ttr on Post Job; can only be lowered afterward, via Set TTR. This auto-rate doesn't run while the job is PAUSED_ADMIN — its unrated tasks just sit there until an admin resolves the job. There's a second, separate deadline for REVISE: if a freelancer doesn't resubmit (and you don't rate the resubmission) within 48 hours of the REVISE, the task is automatically rated NOT_OK instead — ignoring a REVISE doesn't default to a paid outcome the way ignoring a normal submission does.
  • OK / NOT_OK / REVISE — the three outcomes when rating a task: OK (Satisfied — pays the freelancer), NOT_OK (Not Satisfied — rejected), REVISE (sent back to the freelancer to fix). See Rate Single Task. Endpoints that report an already-rated task's outcome (like Get Rated Tasks) use NOK instead of NOT_OK for the negative outcome — same meaning, different spelling depending on whether you're sending a rating or reading one back.
  • PCODE — a code your own site generates (from the job ID, freelancer ID, and your secret key) and displays to the freelancer once they finish the task; they submit it back as proof, and SproutGigs recomputes it to verify the match — so System Verify can check it automatically. See Auto-rating with PCODE.
  • Qualification job — a job in category 9801, used to test/screen freelancers before inviting them to paid work. Has its own rules — see category_id on Post Job.
  • Power Job — a job whose task_value is $2 or more, which changes the fees on both sides. See Power Jobs.
  • System Verify — two of the three autorate values, which check a freelancer's submitted PCODE automatically instead of leaving rating fully manual: V (verifies the PCODE is correct, but leaves rating to you) and V+R (verifies and auto-rates the task OK if it matches). The third value, NO, turns this off entirely — no verification, all rating is manual. See autorate on Post Job.
  • KYC (identity verification) — if your account has a pending KYC request, most job-management endpoints reject requests until you resolve it. See Errors.

Gigs

Gigs are services freelancers list for sale — the opposite direction from Jobs, where you (the buyer) post work and freelancers complete it. The Gigs endpoints are read-only: they let you browse gigs, sellers and reviews to help you decide who to hire. Placing an order to actually hire a seller isn't available through the API yet — once you've found a gig, go to the gig's page on the website to place the order. Two things worth knowing before you do: hiring requires your most recent deposit-type transaction to be a genuine deposit of at least $5 — balance moved from your freelancer earnings into your spendable wallet doesn't count, even if it's enough to cover the gig's price. And once hired, you can only cancel a pending order in the first 15 minutes after placing it, or after 8 hours if the seller hasn't responded — there's no way to cancel in between.

Categories Endpoint

Get the list of gig categories and subcategories, with the minimum price for each subcategory. Each item in the response is one category/subcategory pair (not a nested tree) — group by category_id yourself if you need categories with their subcategories nested.

        GET https://sproutgigs.com/api/gigs/get-categories.php

Example request

        GET /api/gigs/get-categories.php HTTP/1.1
        Host: sproutgigs.com
        Authorization: Basic dXNlcl9pZDphcGlfc2VjcmV0
      

Example response

        [
          {
            "category_id": "02",
            "subcategory_id": "0215",
            "category": "Artificial Intelligence",
            "subcategory": "AI Consulting",
            "min_price": "1.00"
          },
          {
            "category_id": "02",
            "subcategory_id": "0220",
            "category": "Artificial Intelligence",
            "subcategory": "AI Development",
            "min_price": "1.00"
          },

          ...

          {
            "category_id": "95",
            "subcategory_id": "9510",
            "category": "Telemarketing",
            "subcategory": "Supply chain management",
            "min_price": "1.00"
          },
          {
            "category_id": "95",
            "subcategory_id": "9511",
            "category": "Telemarketing",
            "subcategory": "Business Consulting",
            "min_price": "1.00"
          }
        ]
      

Get Gig Endpoint

Get a single gig by id. active_orders counts the seller's active orders across all of their gigs, not just this one — treat it as a signal of how busy the seller currently is, not this specific gig's demand. Likewise, seller_gigs_total and seller_rating_total are aggregated across every gig the seller has, not specific to this one — comparing two gigs from the same seller will show identical numbers for both fields. For this specific gig's own reputation, use rating and reviews_total instead (0 if it has no reviews yet). badge (gold/silver/bronze, or null) reflects the seller's overall rating/review-count tier; sproutgigs_pick (boolean) flags gigs SproutGigs highlights as noteworthy, either by editorial pick or because the gig itself has a strong rating — no further breakdown of why a gig is or isn't flagged is provided. The seller_chats_response_time field is omitted entirely if the seller has never responded to a chat. This lookup isn't filtered by the gig's status — check the status field in the response (DRAFT, UNDER_REVIEW, RUNNING, PAUSED, DECLINED, CANCELLED, DELETED) if you saved a gig_id earlier and need to confirm it's still active before acting on it — only RUNNING gigs are orderable. If gig_id doesn't match any gig, the response is {"ok": false, "message": "Gig not found."}, same as any other not-found error.

        GET https://sproutgigs.com/api/gigs/get-gig.php

Example request

        GET /api/gigs/get-gig.php HTTP/1.1
        Host: sproutgigs.com
        Authorization: Basic dXNlcl9pZDphcGlfc2VjcmV0
        Content-Type: application/json

        {
          "gig_id": "dc716a672cdc"
        }

      

The following attributes are available in the request body:

Attribute Type Required? Default Description
gig_id string yes Id of the gig you want to retrieve.

Example response

        {
          "id": "dc716a672cdc",
          "title": "I Will Setup WordPress/Blogger Website for AD Revenue Approval",
          "category_id": "40",
          "category": "Web Development",
          "subcategory_id": "4001",
          "subcategory": "Web Development",
          "price": 3.11,
          "links": [],
          "images": [
              {
                "url": "https://static.sproutgigs.com/gigs/2023/12/01/d6d49ed7/1608a5b6.png"
              },
              {
                "url": "https://static.sproutgigs.com/gigs/2023/12/01/d6d49ed7/81388834.png"
              },
              {
                "url": "https://static.sproutgigs.com/gigs/2023/12/01/d6d49ed7/f4fe1af6.png"
              },
              {
                "url": "https://static.sproutgigs.com/gigs/2023/12/01/d6d49ed7/708db330.png"
              },
              {
                "url": "https://static.sproutgigs.com/gigs/2023/12/01/d6d49ed7/665b547a.png"
              }
            ],
          "description": "Hello,\r\n\r\n\ud83d\udfeaI will build a WordPress/Blogger website that is ready to apply for  Ad Revenue approval.\r\n\r\n\u2714\ufe0f This gig Includes and ensures that your website looks professional and follows Ad Revenue guidelines\r\n\u2714\ufe0f And 100% Ready to apply for Ad Revenue\r\n\r\n\ud83d\udfeaWith over four years of Ad Revenue experience, my gig offers you a better chance of Ad Revenue approval.\r\n\ud83d\udfeaCheck out my satisfied client's review and images to see my work for yourself.\r\n\r\n\ud83d\udfe9WHAT'S IN THE PACKAGE\r\n\r\n\u2714\ufe0f 100% Responsive and mobile-friendly theme.\r\n\u2714\ufe0f Ad Revenue Ready.\r\n\u2714\ufe0f Google Search Console Configuration.\r\n\u2714\ufe0f Google Analytics Configuration\r\n\u2714\ufe0f Fully customizable theme.\r\n\u2714\ufe0f SEO Setup.\r\n\u2714\ufe0f Table of Content\r\n\u2714\ufe0f 4 Plugins (WordPress)\r\n\u2714\ufe0f 4 Pages (About us - Contact us - Privacy policy - Terms and conditions)\r\n\u2714\ufe0f Custom logo + site icon.\r\n\u2714\ufe0f Header menu + footer.\r\n\u2714\ufe0f Social share button.\r\n\u2714\ufe0f Custom file + widget.\r\n\r\n\r\n\ud83d\udfe5REQUIREMENTS\r\n\r\n\u2714\ufe0f For Blogger - Must have a blogger account or name for your Blog\r\n\u2714\ufe0f For WordPress - Must have a WordPress website\r\n\r\nHurry up!!! Place your order now.\r\n\r\nNote: This Gig does not guarantee at 100% your site is going to be approved by Ad Revenue\"\r\n\r\nRegards,\r\nPolando8",
          "seller_nickname": "Polando8",
          "seller_gigs_total": 952,
          "seller_rating_total": 4.8,
          "seller_member_since": "2020-07-06 22:27:10",
          "seller_avatar": "https://static.sproutgigs.com/avatars/2020/07/06/d6d49ed7_1668183031.png",
          "seller_last_refresh_datetime": "2024-03-04 14:14:32",
          "seller_countrycode": "bd",
          "seller_countryname": "Bangladesh",
          "delivery_time": "1d",
          "revisions": 2,
          "seller_chats_response_time": "3 hrs",
          "published_at": "2024-02-15 08:42:42",
          "status": "RUNNING",
          "active_orders": 40,
          "rating": 4.9,
          "reviews_total": 214,
          "badge": "gold",
          "sproutgigs_pick": true
        }
      

Get Gigs Endpoint

Search and list active gigs. There's no total count or page count in the response — check the next_page field and keep paginating until it's false. Passing search_term overrides all other filters. The cover_image field is only present on gigs that have one uploaded — don't assume every result has it.

        GET https://sproutgigs.com/api/gigs/get-gigs.php

Example request

        GET /api/gigs/get-gigs.php HTTP/1.1
        Host: sproutgigs.com
        Authorization: Basic dXNlcl9pZDphcGlfc2VjcmV0
        Content-Type: application/json

        {
          "page": 1,
          "results_per_page": 10,
          "order": "newest"
        }

      

The following attributes are available in the request body:

Attribute Type Required? Default Description
category_id string no Gig category ID. Use the categories endpoint to get the list of available categories. The category ID must be exactly what is returned in the category endpoint, respecting the leading zeroes that may exist. Ignored if subcategory_ids is also sent.
subcategory_ids string array no List of subcategory IDs. Use the categories endpoint to get the list of available subcategories. The subcategory ID must be exactly what is returned in the category endpoint, respecting the leading zeroes that may exist. The maximum number of subcategories is 10. Takes priority over category_id — send only one of the two.
countries string array no List of two letter countries codes (ISO-3166-1 alpha2). The maximum number of countries is 10.
min_price float Required if max_price is provided Minimum gig price. Silently raised to the site-wide minimum gig price if you send something lower.
max_price float Required if min_price is provided Maximum gig price. If, after the min_price adjustment above, this ends up less than or equal to min_price, the price filter is dropped entirely (no error) and results aren't filtered by price.
search_term string no Filter gigs by title. If provided all other filter parameters will be ignored. Words of 2 characters or fewer are dropped before matching — if every word in your term is that short, the filter has nothing left to match on and you'll get back the full unfiltered list of active gigs instead of an empty result.
page int no 1 The page of gigs you want to retrieve.
results_per_page int no 10 Number of results per page, from 10 to 100. An out-of-range value isn't clamped to the nearest bound — it falls back to the default of 10.
order string no Retrieve gigs sorted by criteria. Leave it blank for default sort (Best Selling). Possible values: newest, oldest, price_highest, price_lowest, reviews_highest, title

Example response

        {
          "current_page": 1,
          "results_per_page": 10,
          "next_page": true,
          "gigs": [
            {
              "id": "ad94f20491f3",
              "title": "I Will Create 1000+  Do-Follow Backlinks (Today Offers)",
              "category_id": "20",
              "category": "Digital Marketing",
              "subcategory_id": "2082",
              "subcategory": "Search Engine Optimization (SEO)",
              "price": 1.04,
              "cover_image": "https://static.sproutgigs.com/gigs/2024/02/15/56184ee3/9de80da4.png",
              "seller_nickname": "TopSeller123",
              "seller_gigs_total": 572,
              "seller_rating_total": 4.8,
              "url": "https://sproutgigs.com/g/ad94f20491f3/i-will-create-1000-do-follow-backlinks-today-offers"
            },
            {
              "id": "dc716a672cdc",
              "title": "I Will Setup WordPress/Blogger Website for AD Revenue Approval",
              "category_id": "40",
              "category": "Web Development",
              "subcategory_id": "4001",
              "subcategory": "Web Development",
              "price": 3.11,
              "cover_image" : "https://static.sproutgigs.com/gigs/2023/12/01/d6d49ed7/1608a5b6.png",
              "seller_nickname": "Polando8",
              "seller_gigs_total": 572,
              "seller_rating_total": 4.8,
              "url": "https://sproutgigs.com/g/dc716a672cdc/i-will-setup-wordpressblogger-website-for-ad-revenue-approval"
            }

            ...

            {
              "id": "96a23a1620b3",
              "title": "I will promote your brand to more than 3.4 million pinterest views",
              "category_id": "20",
              "category": "Digital Marketing",
              "subcategory_id": "2040",
              "subcategory": "Influencer Marketing",
              "price": 1.5,
              "cover_image": "https://static.sproutgigs.com/gigs/2024/01/09/e170e2e2/e1c31d0b.png",
              "seller_nickname": "Tourmalin",
              "seller_gigs_total": 64,
              "seller_rating_total": 4.9,
              "url": "https://sproutgigs.com/g/96a23a1620b3/i-will-promote-your-brand-to-more-than-34-million-pinterest-views"
            },
            {
              "id": "aa3c91d164c0",
              "title": "I will Create Ad revenue Ready Blogger and WordPress Website in 24 Hr",
              "category_id": "40",
              "category": "Web Development",
              "subcategory_id": "4001",
              "subcategory": "Web Development",
              "price": 5.18,
              "cover_image": "https://static.sproutgigs.com/gigs/2024/01/06/d44f67bb/e389164a.png",
              "seller_nickname": "mirzuddin",
              "seller_gigs_total": 98,
              "seller_rating_total": 4.7,
              "url": "https://sproutgigs.com/g/aa3c91d164c0/i-will-create-ad-revenue-ready-blogger-and-wordpress-website-in-24-hr"
            }
          ]
        }
      

Get Gig Public Questions Endpoint

Get the public Q&A for a gig. An answer may be empty if the seller hasn't replied yet. No total count in the response — paginate until next_page is false.

        GET https://sproutgigs.com/api/gigs/get-gig-public-questions.php

Example request

        GET /api/gigs/get-gig-public-questions.php HTTP/1.1
        Host: sproutgigs.com
        Authorization: Basic dXNlcl9pZDphcGlfc2VjcmV0
        Content-Type: application/json

        {
          "gig_id": "dc716a672cdc",
          "page": 1,
          "results_per_page": 10
        }

      

The following attributes are available in the request body:

Attribute Type Required? Default Description
gig_id string yes Id of the gig you want to retrieve public questions for.
page int no 1 The page of public questions you want to retrieve.
results_per_page int no 10 Number of results per page, from 10 to 100. An out-of-range value isn't clamped to the nearest bound — it falls back to the default of 10.
order string no Retrieve gig public questions sorted by criteria. Leave it blank for default sort (Newest). Possible values: likes_highest, likes_lowest, oldest

Example response

        {
          "current_page": 1,
          "results_per_page": 10,
          "next_page": true,
          "questions": [
            {
              "question": "Dear,friend\r\n\r\nIam interested in having a blog according to your gig please let me know what requirements needed and how soon we can start?",
              "answer": "\u1f7e5REQUIREMENTS\r\n\r\n\u2714 For Blogger - Must have a blogger account or name for your Blog\r\n\u2714 For WordPress - Must have a WordPress website\r\n",
              "total_likes": 6,
              "created_at": "2024-02-18 14:02:43",
              "user_countrycode": "kw",
              "user_avatar": "https://static.sproutgigs.com/avatars/2023/07/27/ff9e8636_1690459323.png",
              "user_nickname": "zarari",
              "user_countryname": "Kuwait"
            },
            {
              "question": "Hello my friend, can you provide a website in Arabic? ",
              "answer": "Your site can be in any language you wish to be. ",
              "total_likes": 0,
              "created_at": "2024-02-16 10:23:13",
              "user_countrycode": "dz",
              "user_avatar": "https://sproutgigs.com/assets/images/profile_no_image.gif",
              "user_nickname": "Abibas33",
              "user_countryname": "Algeria"
            },

            ...

            {
              "question": "please i would like to hire your services what would be the procedure, i want you to build a blog, like this one https://blog.zulu.id/?job=aa33cd9083ab&worker=99301ea1 what would be the procedure and values please",
              "answer": "You need an AdSense approved website. You can place an order to start the process. ",
              "total_likes": 8,
              "created_at": "2024-01-08 14:59:00",
              "user_countrycode": "br",
              "user_avatar": "https://static.sproutgigs.com/avatars/2023/12/16/99907fbc_1702734799.png",
              "user_nickname": "Lindaosoueu",
              "user_countryname": "Brazil"
            },
            {
              "question": "what is ad revenue? can you send me this company link?\r\n\r\n",
              "answer": "It's AdSense.\r\n\r\n",
              "total_likes": 10,
              "created_at": "2024-01-05 00:15:44",
              "user_countrycode": "ng",
              "user_avatar": "https://static.sproutgigs.com/avatars/2023/11/14/5b502594_1704413256.png",
              "user_nickname": "ABUTECH",
              "user_countryname": "Nigeria"
            }
          ]
        }
      

Get Gig Reviews Endpoint

Get reviews for a gig. Each item in the response represents one completed order, not one review — it groups the seller's and buyer's review of that same order into a single {"seller": {...}, "buyer": {...}} object (either side may be missing if they haven't reviewed yet). No total count — paginate until next_page is false.

        GET https://sproutgigs.com/api/gigs/get-gig-reviews.php

Example request

        GET /api/gigs/get-gig-reviews.php HTTP/1.1
        Host: sproutgigs.com
        Authorization: Basic dXNlcl9pZDphcGlfc2VjcmV0
        Content-Type: application/json

        {
          "gig_id": "dc716a672cdc",
          "page": 1,
          "results_per_page": 10
        }

      

The following attributes are available in the request body:

Attribute Type Required? Default Description
gig_id string yes Id of the gig you want to retrieve reviews for.
page int no 1 The page of reviews you want to retrieve.
results_per_page int no 10 Number of results per page, from 10 to 100. An out-of-range value isn't clamped to the nearest bound — it falls back to the default of 10.
order string no Retrieve gig reviews sorted by criteria. Leave it blank for default sort (Newest). Possible values: oldest

Example response

        {
          "current_page": 1,
          "results_per_page": 10,
          "next_page": true,
          "reviews": [
            {
              "buyer": {
                "rating": "5",
                "comment": "Your work is very nice. I like it",
                "created_at": "2024-02-03 09:04:19",
                "user_countrycode": "lk",
                "user_nickname": "oppv",
                "user_countryname": "Sri Lanka",
                "user_avatar": "https://sproutgigs.com/assets/images/profile_no_image.gif"
              },
              "seller": {
                "rating": "5",
                "comment": "Thanks for ordering, and I hope to see you again! Have a wonderful rest of your day.",
                "created_at": "2024-02-03 21:14:04",
                "user_countrycode": "bd",
                "user_nickname": "Polando8",
                "user_countryname": "Bangladesh",
                "user_avatar": "https://static.sproutgigs.com/avatars/2020/07/06/d6d49ed7_1668183031.png"
              }
            },
            {
              "buyer": {
                "rating": "5",
                "comment": "Thank you very much \u1f60a",
                "created_at": "2024-02-05 06:55:26",
                "user_countrycode": "us",
                "user_nickname": "Narcisse1992",
                "user_countryname": "United States",
                "user_avatar": "https://sproutgigs.com/assets/images/profile_no_image.gif"
              },
              "seller": {
                "rating": "5",
                "comment": "Patient, understanding, and a pleasure to work with. Hope to see you again. Have a great rest of your day.",
                "created_at": "2024-02-05 07:04:18",
                "user_countrycode": "bd",
                "user_nickname": "Polando8",
                "user_countryname": "Bangladesh",
                "user_avatar": "https://static.sproutgigs.com/avatars/2020/07/06/d6d49ed7_1668183031.png"
              }
            },

              ...

            {
              "buyer": {
                "rating": "4",
                "comment": "Good.",
                "created_at": "2023-10-16 23:55:27",
                "user_countrycode": "bj",
                "user_nickname": "JulesP",
                "user_countryname": "Benin",
                "user_avatar": "https://static.sproutgigs.com/avatars/2020/01/14/8ffac5f3_1688379232.png"
              },
              "seller": {
                "rating": "4",
                "comment": "Super understanding person.",
                "created_at": "2023-10-18 05:46:01",
                "user_countrycode": "bd",
                "user_nickname": "Polando8",
                "user_countryname": "Bangladesh",
                "user_avatar": "https://static.sproutgigs.com/avatars/2020/07/06/d6d49ed7_1668183031.png"
              }
            },
            {
              "buyer": {
                "rating": "4",
                "comment": "GOOD JOB",
                "created_at": "2023-09-23 23:43:57",
                "user_countrycode": "ma",
                "user_nickname": "kanouz",
                "user_countryname": "Morocco",
                "user_avatar": "https://sproutgigs.com/assets/images/profile_no_image.gif"
              },
              "seller": {
                "rating": "4",
                "comment": "Great client",
                "created_at": "2023-09-23 23:52:14",
                "user_countrycode": "bd",
                "user_nickname": "Polando8",
                "user_countryname": "Bangladesh",
                "user_avatar": "https://static.sproutgigs.com/avatars/2020/07/06/d6d49ed7_1668183031.png"
              }
            }
          ]
        }
      

Jobs

The Jobs endpoints let you post, manage and rate paid work for freelancers to complete — the opposite direction from Gigs, where freelancers list services for you to buy. A job is broken into tasks; freelancers pick up a task, follow your instructions, and submit proof to get paid.

To create a job you'll need a zone_id (plus optional excluded_countries) or a list_id if you're targeting a freelancer list — either one of your own, or a public list from another buyer or from SproutGigs itself — and a category_id — the most up-to-date values for these come from the zones, lists and categories endpoints below. See the Post Job endpoint for the full posting flow, including the different job types and how cost is calculated.

How Job Ranking Works

When a freelancer browses the job list, jobs are ordered in three layers:

  1. Featured jobs (bought via a bid, see Get Predicted Position below) always sort first.
  2. Among the remaining jobs, a fixed grouping is applied: jobs the freelancer already has a task on hold for, then jobs from a private list the freelancer belongs to, then jobs in "express" categories, then everything else.
  3. Within each of those groups, jobs are ordered by whatever sort the freelancer has selected (Newest, Cost, Best Rate, TTR, etc).

The speed field (see the Post Job parameters below) does not affect this ordering. It only controls whether a job is included at all in a given page load: on each load, a random number is drawn and the job is shown only if its speed beats that number — so a speed of 100 means roughly a 10% chance of appearing on any single page load, while 1000 always shows it. Once a job is included, its position is determined solely by the three layers above, not by speed.

Job Status Values

The status field returned by Get Job/Get Jobs can be:

Several of these statuses can change automatically, without any action from you — not just the ones explicitly named "system." Don't assume a status only ever changes because you called an endpoint; poll Get Job or listen for the Job Status Changed webhook if you need to react promptly.

  • RUNNING — live, accepting and paying for tasks.
  • PAUSED — not accepting new work. Usually paused by you (Pause Job) or set as the job's starting state because you set pause_after_approval or a future scheduled_start_at — but a job can also land here without you doing anything, if your account gets suspended for inactivity or another account-level issue. Resume it with Resume Job; if it's paused because of a future scheduled_start_at, it resumes on its own once that time is reached, no action needed.
  • PAUSED_ADMIN — paused by an admin, or automatically if an unusually high share of a job's ratings come back NOT_OK. Resuming it is admin-only — it doesn't recover on its own the way PAUSED_SYSTEM does, and isn't something you or the API can trigger.
  • PAUSED_SYSTEM — paused automatically because every open position is currently filled or held by a worker mid-task. Resumes on its own once a position frees up, which can happen several ways: you add positions, you rate a task NOT_OK, or a worker's hold on a task expires or is released (a freelancer can only hold one task at a time platform-wide — starting a new hold automatically releases any other job's hold they had, with its hold fee refunded). If a worker's hold expires or is released without submission while the job is still active (any status other than FINISHED/DECLINED/BLOCKED), the position simply reopens for another worker — no refund. If the job has already ended by then, you're refunded that position's cost (task value plus its proportional fee) instead, since it can no longer be filled.
  • PENDING_APPROVAL — reached only while a job is under review (from PENDING_REVIEW) or being reconsidered after a decline (from DECLINED): instead of approving or declining it outright, an admin suggested changes (for example to price, targeting, or requirements) and is waiting for you to approve or reject them. There's no API endpoint for this yet — you'll need to review and respond on the website. Most management actions are blocked until you do. Rejecting the changes declines the job outright (DECLINED) rather than restoring it to how it was before.
  • PENDING_RESTART — you used Restart Job on a FINISHED job and your account isn't on auto-approval; awaiting the same single manual review as PENDING_REVIEW. Editing a finished job's content instead of restarting it goes to PENDING_REVIEW, not here. You can also cancel it outright instead of waiting, which finishes the job and refunds what you'd be charged for the restart — currently only from the website, not the API.
  • PENDING_REVIEW — awaiting manual approval (see "Approval" under Post Job below). Once approved, becomes PAUSED if you set pause_after_approval or a future scheduled_start_at — otherwise becomes RUNNING. You can also cancel it outright instead of waiting, which finishes the job and refunds what you paid — currently only from the website, not the API.
  • BLOCKED — an admin terminated the job without a refund. Genuinely terminal — unlike the other two below, there's no path back for this one, not even for admins. Contact support.
  • DECLINED — rejected during review, or terminated by an admin with a refund. Not fully terminal: an admin can re-approve it straight back to RUNNING/PAUSED, and — same as FINISHED below — editing its content also brings it back (to RUNNING, PAUSED, or PENDING_REVIEW, depending on your account's approval settings).
  • FINISHED — stopped by you, ran out of funded positions, or auto-closed after a long stretch of inactivity. Not fully terminal: Restart Job brings it back (re-charging you for positions), and so does editing its content (to RUNNING, PAUSED, or PENDING_REVIEW, depending on your account's approval settings).

Power Jobs

A job automatically becomes a "Power Job" once its task_value is $2 or more — there's no separate flag or category, it's purely based on the price you set. Power Jobs trade a lower fee for you against a cost to the freelancer: you pay the Power Jobs campaign fee rate instead of the regular one (lower than standard, meant to make posting high-value work more attractive, and not fixed — it can vary per account and change over time; your current rate is shown on the Pricing page), while freelancers have a flat surcharge deducted from their payout on top of that, automatically, on every task rated OK. Unlike your rate, the freelancer surcharge is a single fixed percentage that applies platform-wide, also shown on the Pricing page. Since this affects what freelancers actually take home, it's worth keeping in mind when setting task_value near the $2 threshold — a job at or above it earns you a lower fee, but nets freelancers less than the sticker price.

Add Positions Endpoint

Add extra positions to a job, without stopping or editing anything else about it — you're charged for the added positions the same way as when the job was first posted. Works on a job that's RUNNING, PAUSED, PAUSED_SYSTEM, PENDING_REVIEW, or PENDING_RESTART. A PAUSED_SYSTEM job automatically switches to RUNNING once the new positions are added (freeing up capacity is exactly what it was waiting for); a plain PAUSED job stays paused. Same as at Post Job, a qualification job's total positions (existing plus added) can't exceed 1000.

        POST https://sproutgigs.com/api/jobs/add-positions.php

Example request

        POST /api/jobs/add-positions.php HTTP/1.1
        Host: sproutgigs.com
        Authorization: Basic dXNlcl9pZDphcGlfc2VjcmV0
        Content-Type: application/json

        {
          "job_id": "fc7b3bd10d08",
          "positions": 1
        }
      

The following fields can be added in the request body:

Attribute Type Required? Default Description
job_id string yes Id of the job you want to add positions to.
positions int yes Number of positions to add in that job. From 1 to 9999.

Example response

        {
          "ok": true,
          "message": "The position(s) has been added."
        }
      

Edit Targeting Endpoint new

Edit the targeting (country selection) of a job. Can only be changed once every 3 hours. Works on a job in any status except PENDING_APPROVAL. Rejected on a list-targeted job — those aren't targeted by country, so there's nothing here to edit. The available zones and their excludable countries can be retrieved from the Get Zones endpoint.

        POST https://sproutgigs.com/api/jobs/edit-targeting.php

Example request

        POST /api/jobs/edit-targeting.php HTTP/1.1
        Host: sproutgigs.com
        Authorization: Basic dXNlcl9pZDphcGlfc2VjcmV0
        Content-Type: application/json

        {
          "job_id": "fc7b3bd10d08",
          "excluded_countries": ["us", "uk"]
        }
      

The following fields can be added in the request body:

Attribute Type Required? Default Description
job_id string yes Id of the job you want to edit the targeting for.
excluded_countries array yes List of country codes to exclude. For int zone jobs, only countries listed in countries_can_be_excluded (from the Get Zones endpoint) are accepted, capped at 10 exclusions — except for SEO category jobs (category id starting with "10"), which allow up to 20. For zone-specific jobs, the remaining countries after exclusion become the targeted ones — at least one must remain, and there's no fixed cap on how many you exclude. Pass an empty array to target all available countries.

Example response

        {
          "ok": true,
          "message": "Job targeting updated successfully."
        }
      

Feature Job Endpoint

Feature a running job to boost its position in the job list, without stopping or editing it (the same thing can also be set upfront at creation time via premium_amount on Post Job). Pay amount (min $2.00) — a higher bid than other featured jobs in the same category wins a better spot, and the bid auto-renews daily for days as long as the job keeps running and you have funds. Instead of paying cash, you can spend a feature-job credit via premium_credit — these are earned automatically (see Lists for one way to earn one); there's currently no API endpoint to check your credit balance ahead of time, only on the website. Call the Get Predicted Position endpoint first to see where a given bid would land you before committing. Two hard requirements: the job must currently be RUNNING (rejected otherwise), and it must not already be featured — there's no "raise my existing bid" call, so to change the amount you have to wait for the current bid to lapse first.

        POST https://sproutgigs.com/api/jobs/feature-job.php

Example request

        POST /api/jobs/feature-job.php HTTP/1.1
        Host: sproutgigs.com
        Authorization: Basic dXNlcl9pZDphcGlfc2VjcmV0
        Content-Type: application/json

        {
          "job_id": "fc7b3bd10d08",
          "amount": 5.00,
          "days": 1
        }
      

The following fields can be added in the request body:

Attribute Type Required? Default Description
job_id string yes Id of the job to be featured.
amount float conditionally required Amount to be spent on featuring the job. Higher amounts may position your job higher in the list of available jobs. Minimum amount is $2.00. Not required if premium_credit is true.
days integer no 1 Period in days to feature the job. It will get renewed every 24 hours if the job is still running and your account has enough funds.
premium_credit boolean no false If true, features the job using one of your feature-job credits instead of charging amount — rejected if you don't have any. promotion_credit (integer, 0/1) is also accepted as an older alias for this same field, kept for backward compatibility — use premium_credit for new integrations.

Example response

        {
          "ok": true
        }
      

Get Categories Endpoint

Get the list of categories, the minimum payment per task you must set to run the job, and the minimum number of freelancers (num_tasks for zone-targeted jobs, list size for list-targeted jobs) — both vary per category, there's no single fixed minimum across the platform.
For a list job, please use the international zone pricing as the minimum payment per task.

        GET https://sproutgigs.com/api/jobs/get-categories.php

Example request

        GET /api/jobs/get-categories.php HTTP/1.1
        Host: sproutgigs.com
        Authorization: Basic dXNlcl9pZDphcGlfc2VjcmV0
      

Example response

        [
          {
            "id": "0500",
            "category": "Sign up",
            "subcategory": "Email submit only",
            "min_workers": 10,
            "min_workers_list": 1,
            "min_task_value": {
              "int": "0.080",
              "west1": "0.240",
              "europe1": "0.200",
              "europe2": "0.160",
              "asia1": "0.100",
              "africa1": "0.100",
              "latin": "0.100",
              "muslim": "0.100",
              "arab1": "0.100"
            }
          },
          {
            "id": "0501",
            "category": "Sign up",
            "subcategory": "Simple Sign up",
            "min_workers": 10,
            "min_workers_list": 1,
            "min_task_value": {
              "int": "0.080",
              "west1": "0.240",
              "europe1": "0.200",
              "europe2": "0.160",
              "asia1": "0.100",
              "africa1": "0.100",
              "latin": "0.100",
              "muslim": "0.100",
              "arab1": "0.100"
            }
          },

          ...

          {
            "id": "9002",
            "category": "Surveys / Offers",
            "subcategory": "Up to 50 questions",
            "min_workers": 10,
            "min_workers_list": 1,
            "min_task_value": {
              "int": "0.500",
              "west1": "1.200",
              "europe1": "1.000",
              "europe2": "0.800",
              "asia1": "0.600",
              "africa1": "0.600",
              "latin": "0.600",
              "muslim": "0.600",
              "arab1": "0.600"
            }
          },
          {
            "id": "9900",
            "category": "Other",
            "subcategory": "Describe and set acceptable price",
            "min_workers": 10,
            "min_workers_list": 1,
            "min_task_value": {
              "int": "0.050",
              "west1": "0.150",
              "europe1": "0.130",
              "europe2": "0.100",
              "asia1": "0.060",
              "africa1": "0.060",
              "latin": "0.060",
              "muslim": "0.060",
              "arab1": "0.060"
            }
          }
        ]
      

min_workers is the minimum you must set num_tasks to when posting a zone-targeted job in this category; min_workers_list is the minimum size a list must have to be used for a list-targeted job in this category (see list_id on Post Job). Posting below either minimum is rejected.

Get Job Analytics Endpoint new

Get performance data for a job — impressions, views, average listing position, tasks submitted, and conversion rate. periods breaks this down by each window the job spent RUNNING (a job paused and resumed several times has one entry per window; the current window has end: null if the job is still running) — all_time is the same data rolled up across the job's entire history. If the job has never run, both come back empty/zeroed rather than an error.

        GET https://sproutgigs.com/api/jobs/get-job-analytics.php

Example request

        GET /api/jobs/get-job-analytics.php?job_id=fc7b3bd10d08 HTTP/1.1
        Host: sproutgigs.com
        Authorization: Basic dXNlcl9pZDphcGlfc2VjcmV0
      

The following fields can be added in the query string:

Attribute Type Required? Default Description
job_id string yes Id of the job to get analytics for.
hourly boolean no false If true, includes an hour-by-hour breakdown under hourly, paginated 500 rows (roughly 3 weeks) per page — omitted by default to keep the response light for long-running jobs.
page int no 1 Page of the hourly breakdown to retrieve. Ignored unless hourly is true.

Example response

        {
          "ok": true,
          "job_id": "fc7b3bd10d08",
          "all_time": {
            "impressions": 18420,
            "quick_views": 640,
            "views": 512,
            "avg_position_global": 3.4,
            "avg_position_category": 2.1,
            "avg_position_subcategory": 1.8,
            "tasks_submitted": 210,
            "conversion_rate": 41.0
          },
          "periods": [
            {
              "start": "2026-08-15T09:00:00Z",
              "end": null,
              "impressions": 9220,
              "quick_views": 340,
              "views": 212,
              "avg_position_global": 3.1,
              "avg_position_category": 1.9,
              "avg_position_subcategory": 1.6,
              "tasks_submitted": 70,
              "conversion_rate": 33.0
            },
            {
              "start": "2026-08-01T00:00:00Z",
              "end": "2026-08-10T00:00:00Z",
              "impressions": 9200,
              "quick_views": 300,
              "views": 300,
              "avg_position_global": 3.7,
              "avg_position_category": 2.3,
              "avg_position_subcategory": 2.0,
              "tasks_submitted": 140,
              "conversion_rate": 46.7
            }
          ]
        }
      

Example response with hourly=true

        {
          "ok": true,
          "job_id": "fc7b3bd10d08",
          "all_time": { "...": "..." },
          "periods": [ { "...": "..." } ],
          "hourly": {
            "current_page": 1,
            "pages": 2,
            "data": [
              {
                "hour": "2026-08-15T09:00:00Z",
                "impressions": 38,
                "quick_views": 2,
                "views": 1
              }
            ]
          }
        }
      

Get Job Endpoint

Get the full detail of a single job by id, including its current status, instructions, proofs, and challenges. Some fields are only present when relevant — for example finished_at only appears once the job is FINISHED, list_id replaces zone_id/excluded_countries for list-targeted jobs, blocked_at/blocked_reason only appear once the job is BLOCKED, variables is only present for jobs posted with variable placeholders in their instructions (unrelated to dynamic_instructions, which reflects the separate dynamic_endpoint feature and is never combined with variables on the same job), and watch_time is omitted entirely for accounts without auto-approval enabled.

        GET https://sproutgigs.com/api/jobs/get-job.php

Example request

        GET /api/jobs/get-job.php HTTP/1.1
        Host: sproutgigs.com
        Authorization: Basic dXNlcl9pZDphcGlfc2VjcmV0
      

The following fields can be added in the query string:

Attribute Type Required? Default Description
job_id string yes Id of the job you want to retrieve.

Example response

        {
          "id": "0950e7d99b65",
          "id_user": "67d33033",
          "zone_id": "int",
          "excluded_countries": [
              "pk",
              "bd",
              "in"
          ],
          "category_id": "2004",
          "created_at": "2021-01-25T07:42:35Z",
          "status": "PAUSED",
          "task_value": 0.06,
          "tasks_done": 3741,
          "num_tasks": 4030,
          "unrated_tasks": 64,
          "workers_max_tasks": 1,
          "workers_level": "starter",
          "speed": 1000,
          "ttr": 7,
          "autorate": "NO",
          "pause_after_approval": 0,
          "scheduled_start_at": "2026-11-30 13:41:22",
          "hold_time": 15,
          "hold_required": 0,
          "watch_time": 0,
          "title": "Play Video",
          "instructions": [
              "Go to url",
              "Play the video."
          ],
          "dynamic_instructions": {"enabled": false},
          "notes": "",
          "proofs": [
              {
                  "description": "example",
                  "type": "screenshot"
              }
          ],
          "challenge_action": "",
          "challenges": [],
          "distribution": 25,
          "daily_tasks_limit": 0,
          "daily_tasks_done": 5,
          "hourly_tasks_limit": 0,
          "hourly_tasks_done": 2
        }
      

Get Jobs Endpoint

Get your jobs. Archived jobs will not be retrieved. Filter by status or by unrated_tasks (jobs that currently have unrated tasks waiting on you), and sort by creation date with order. Results are paginated 50 per page — check pages in the response and iterate through all pages to get everything. Same conditional fields as Get Job apply to each job in the list.

        GET https://sproutgigs.com/api/jobs/get-jobs.php

Example request

        GET /api/jobs/get-jobs.php HTTP/1.1
        Host: sproutgigs.com
        Authorization: Basic dXNlcl9pZDphcGlfc2VjcmV0
      

The following fields can be added in the query string:

Attribute Type Required? Default Description
page int no 1 The page of jobs you want to retrieve.
status string no You can filter the retrieved jobs by status. Possible values are: running, paused, paused_admin, paused_system, pending_approval, pending_restart, pending_review, blocked, declined, finished
unrated_tasks int no 0 Retrieve jobs with unrated tasks only. Possible values are 0 and 1.
order string no asc Retrieve jobs sorted by creation date. Possible values: asc, desc

Example response

        {
          "current_page": 1,
          "pages": 1,
          "jobs": [
            {
              "id": "0950e7d99b65",
              "id_user": "abcd1234",
              "zone_id": "int",
              "excluded_countries": [],
              "category_id": "2004",
              "created_at": "2021-10-25T07:42:35Z",
              "status": "RUNNING",
              "task_value": 0.06,
              "tasks_done": 3741,
              "num_tasks": 4030,
              "unrated_tasks": 4,
              "workers_max_tasks": 1,
              "workers_level": "starter",
              "speed": 1000,
              "ttr": 7,
              "autorate": "NO",
              "pause_after_approval": 0,
              "scheduled_start_at": "2026-11-30 13:41:22",
              "hold_time": 15,
              "hold_required": 0,
              "watch_time": 0,
              "title": "Play Video",
              "instructions": [
                "Go to https://video-website.io/watch/1",
                "Play the video."
              ],
              "dynamic_instructions": {"enabled": false},
              "notes": "",
              "proofs": [
                {
                  "description": "FULL screenshot showing video is playing.",
                  "type": "screenshot"
                }
              ],
              "challenge_action": "",
              "challenges": [],
              "daily_tasks_limit": 0,
              "daily_tasks_done": 5,
              "hourly_tasks_limit": 0,
              "hourly_tasks_done": 2
            }
          ]
        }
      

Lists Endpoint

Get your own custom lists of freelancers, to use their id as list_id when posting a list-targeted job. This only returns lists you created — to browse public lists from other buyers (or from SproutGigs itself), use the Get Public Lists endpoint instead.
The minimum list size accepted for a list-targeted job varies per category — check min_workers_list on the Get Categories endpoint. Lists smaller than that minimum are rejected at posting time.
Some lists are automatically maintained by SproutGigs rather than by you (autogenerated: true) — you can still target a job at one, but Add Freelancers rejects any attempt to add freelancers to it manually.

        GET https://sproutgigs.com/api/jobs/get-lists.php

Example request

        GET /api/jobs/get-lists.php HTTP/1.1
        Host: sproutgigs.com
        Authorization: Basic dXNlcl9pZDphcGlfc2VjcmV0
      

Example response

        [
          {
            "id": 12870,
            "name": "Successfully Completed",
            "workers": 147,
            "public": false,
            "autogenerated": true
          },
          {
            "id": 14118,
            "name": "Awesome freelancers",
            "workers": 102,
            "public": true,
            "autogenerated": false
          },
          {
            "id": 14256,
            "name": "Freelancers from Brazil",
            "workers": 53,
            "public": false,
            "autogenerated": false
          },
          {
            "id": 16329,
            "name": "My special list",
            "workers": 18,
            "public": false,
            "autogenerated": false
          }
        ]
      

Get Predicted Position Endpoint

Check the predicted position your job will show up in the list with and without the category filter, and/or the current maximum bid amount overall and within a category. Higher bids improve your job position. Pass amount to get predicted positions, category_id to scope results to a category, or both. Fields that were not requested or could not be computed are returned as null.

        POST https://sproutgigs.com/api/jobs/get-predicted-position.php

Example request

        POST /api/jobs/get-predicted-position.php HTTP/1.1
        Host: sproutgigs.com
        Authorization: Basic dXNlcl9pZDphcGlfc2VjcmV0
        Content-Type: application/json

        {
          "category_id": "2501",
          "amount": 5.00
        }
      
Attribute Type Required? Default Description
category_id string no Category ID to publish the job. Use the categories endpoint to get the list of available categories. The category ID must be exactly what is returned in the category endpoint, respecting the leading zeroes that may exist. When omitted, the *_in_category response fields are null.
amount float no Amount to be spent on featuring the job. Higher amounts may position your job higher in the list of available jobs. Minimum amount is $2.00. When omitted, the position_in_* response fields are null.

Example response

        {
          "position_in_all": 1,
          "position_in_category": 1,
          "first_in_all": 12.5,
          "first_in_category": 8.0
        }
      

Get Rated Tasks Endpoint

Get tasks that have already been rated OK or NOK, for a specific job or across all your jobs — useful for auditing history rather than acting on pending work (see Get Unrated Tasks for that). Results are paginated 100 per page. Make sure to iterate through all pages to get all the tasks. Any screenshot URL in a proof is temporary and will eventually stop working — don't store it for later use; if you need to keep the image, download and save it yourself when you fetch it.

        GET https://sproutgigs.com/api/jobs/get-rated-tasks.php

Example request

        GET /api/jobs/get-rated-tasks.php HTTP/1.1
        Host: sproutgigs.com
        Authorization: Basic dXNlcl9pZDphcGlfc2VjcmV0
      

The following fields can be added in the query string:

Attribute Type Required? Default Description
page int no 1 The page of tasks you want to retrieve.
job_id string no Get the rated tasks of a specific job. If empty, the rated tasks of all your jobs will be retrieved.
task_ids string array no Get the specified rated tasks of a specific job. Separate values by comma.

Example response

        {
          "current_page": 1,
          "pages": 1,
          "tasks": [
            {
              "id": "158004285a3523",
              "job_id": "abcdef123456",
              "worker_id": "abcd1234",
              "finished_at": "2021-11-01T17:04:45Z",
              "ip_address": "127.0.0.1",
              "country_code": "XX",
              "revision_number": 1,
              "variables": [],
              "status": "OK",
              "proofs": [
                {
                  "text": "latest submitted proof"
                }
              ],
              "previous_proofs": [
                {
                  "employer_comment": "Sorry, the answer is incorrect. Please try again.",
                  "finished_at": "2021-02-07 09:59:41",
                  "proofs": [
                    {
                      "text": "previous unnacepted proof"
                    }
                  ]
                }
              ]
            }
          ]
        }
      

Get Unrated Tasks Endpoint

Get tasks still awaiting your rating, for a specific job or across all your jobs — this is the list to act on before each task's TTR deadline passes (after which it's automatically rated OK). Results are paginated 100 per page. Make sure to iterate through all pages to get all the tasks. Submissions from newer freelancer accounts may go through an internal check before appearing here — if your submitted-task count doesn't match what you expect, this is usually why. Any screenshot URL in a proof is temporary (see the note on Get Rated Tasks) — don't store it for later use.

        GET https://sproutgigs.com/api/jobs/get-unrated-tasks.php

Example request

        GET /api/jobs/get-unrated-tasks.php HTTP/1.1
        Host: sproutgigs.com
        Authorization: Basic dXNlcl9pZDphcGlfc2VjcmV0
      

Example request with parameters

        GET /api/jobs/get-unrated-tasks.php?job_id=abc123dfae98&task_ids=99900012abcd1f,99923817f2bce4,99924617ab23df HTTP/1.1
        Host: sproutgigs.com
        Authorization: Basic dXNlcl9pZDphcGlfc2VjcmV0
      

The following fields can be added in the query string:

Attribute Type Required? Default Description
page int no 1 The page of tasks you want to retrieve.
job_id string no Get the unrated tasks of a specific job. If empty, the unrated tasks of all your jobs will be retrieved.
task_ids string array no Get the specified unrated tasks of a specific job. Separate values by comma.

Example response

        {
          "current_page": 1,
          "pages": 1,
          "tasks": [
            {
              "id": "158004285a3523",
              "job_id": "abcdef123456",
              "worker_id": "abcd1234",
              "finished_at": "2021-11-01T17:04:45Z",
              "ip_address": "127.0.0.1",
              "country_code": "XX",
              "revision_number": 0,
              "variables": [],
              "proofs": [
                {
                  "text": "submitted proof"
                }
              ]
            }
          ]
        }
      

Get Zones Endpoint

Get the available targeting zones and, for each one, the countries that can be excluded via excluded_countries. Zone int is worldwide; the others are regional bundles. Prices differ by zone and category — see the Get Categories endpoint for the minimum task_value per zone.

        GET https://sproutgigs.com/api/jobs/get-zones.php

Example request

        GET /api/jobs/get-zones.php HTTP/1.1
        Host: sproutgigs.com
        Authorization: Basic dXNlcl9pZDphcGlfc2VjcmV0
      

Example response

        [
          {
            "id": "africa1",
            "zone": "Africa",
            "excludable_countries": [ "ao", "bw", "cg", "eg", "et", "gh", "ke", "ly", "ma", "mz", "ng", "rw", "za", "tz", "ug", "zw", "tn" ]
          },
          {
            "id": "arab1",
            "zone": "Arab Countries",
            "excludable_countries": [ "ae", "bh", "kw", "sa", "ye", "qa", "om", "jo", "sy", "lb", "ps", "iq", "eg", "ma", "ly", "tn", "dz", "sd", "mr", "so", "dj", "km" ]
          },
          {
            "id": "asia1",
            "zone": "Asia",
            "excludable_countries": [ "bd", "cn", "in", "id", "jp", "kr", "lk", "my", "pk", "ph", "sg", "th", "vn" ]
          },
          {
            "id": "europe1",
            "zone": "Europe West",
            "excludable_countries": [ "at", "be", "ch", "de", "dk", "es", "fi", "fr", "uk", "ie", "is", "it", "lu", "mc", "no", "pt", "se", "sm" ]
          },
          {
            "id": "europe2",
            "zone": "Europe East",
            "excludable_countries": [ "al", "am", "by", "ba", "bg", "cy", "cz", "ee", "gr", "hu", "hr", "lt", "mk", "mt", "rs", "ru", "si", "sk", "tr", "ua", "pl", "ro" ]
          },
          {
            "id": "int",
            "zone": "International",
            "excludable_countries": [ "al", "pk", "bd", "id", "in", "ph", "ro", "eg", "pl", "my", "np", "vn", "cn", "lt", "ma", "us", "ca", "uk", "au", "de", "fr", "lk", "si", "ve", "co" ]
          },
          {
            "id": "latin",
            "zone": "Latin America",
            "excludable_countries": [ "ar", "bo", "br", "cl", "co", "ec", "fk", "gf", "gy", "mx", "py", "pe", "sr", "uy", "ve" ]
          },
          {
            "id": "muslim",
            "zone": "Muslim Countries",
            "excludable_countries": [ "dz", "id", "in", "pk", "bd", "ma", "ng", "eg", "ir", "tr", "tn" ]
          },
          {
            "id": "west1",
            "zone": "USA & Western",
            "excludable_countries": [ "us", "uk", "ca", "au", "nz" ]
          }
        ]
      

Pause Job Endpoint

Pause a running job — freelancers stop seeing it, but held/in-progress tasks and your funds are untouched, and you can resume it later. This holds true even when the job pauses itself (PAUSED_SYSTEM) — funds already reserved for the job stay locked for as long as it's paused, with no timeout; only Stop Job releases unused funds. Pausing too often in a short period triggers an escalating cooldown before you can pause again. A rejected request includes how many minutes are left to wait.

        POST https://sproutgigs.com/api/jobs/job-pause.php

Example request

        POST /api/jobs/job-pause.php HTTP/1.1
        Host: sproutgigs.com
        Authorization: Basic dXNlcl9pZDphcGlfc2VjcmV0
        Content-Type: application/json

        {
          "job_id": "fc7b3bd10d08"
        }
      

The following fields can be added in the request body:

Attribute Type Required? Default Description
job_id string yes Id of the job to be paused.

Example response

        {
          "ok": true
        }
      

Post Job Endpoint

Post a new job for freelancers to complete. A job is made up of one or more tasks: freelancers pick up a task, follow your instructions, submit the requested proof, and get paid the task_value amount once the task is rated OK — either by you manually, or automatically if the job uses System Verify (autorate V+R) and the freelancer's PCODE matches, or if the TTR deadline passes without you rating it. Note that a wrong answer to a challenges question works the other way — it auto-rates the task NOT_OK on the spot (challenges never auto-rate a task OK, and only auto-rate at all when autorate is NO).

There's no explicit "job type" parameter — the API infers it from which fields you send:

  • Classic (the default): the most flexible option, with full control over targeting (zone_id / excluded_countries), worker filters, variables, and dynamic instructions. This is what you get when list_id is omitted and category_id does not start with "01" (Express Jobs).
  • Express: a streamlined job type for quick, simple tasks. Triggered by using a category_id that starts with "01" — these categories use their own approval and campaign fee rates.
  • List: only freelancers from a specific freelancer list can pick up the job — one of your own (see the Get Lists endpoint) or a public list from another buyer or from SproutGigs itself (see Get Public Lists). Triggered by sending list_id instead of zone_id — country targeting and excluded_countries don't apply, worker sex targeting is ignored, and the list must have at least the minimum number of freelancers required for the job. Posting to a list also emails every member of the list about the new job, regardless of your notify_followers setting. Unlike Classic/Express, the campaign fee here has a minimum dollar amount per task, not just a percentage — for low task_value jobs, the effective fee can end up well above the plain percentage rate; test: 1 will show the real number. If you send both list_id and an Express category_id, list_id wins for fee purposes — the Express rates never apply.

Fees, minimum positions and a few other rules vary slightly by type — see the individual field descriptions below, and use test: 1 to get the exact estimated cost for your specific job before posting it.

        POST https://sproutgigs.com/api/jobs/post-job.php

Before you post: you need funds in your spendable balance — deposit via Wallet > Deposits on the website (there's no deposit API endpoint). Posting a job with insufficient funds fails; use test: 1 (below) to check the cost first. Posting a job debits the full cost (task cost + fees) from your spendable balance immediately, in the same request — even if the job is created as PENDING_REVIEW and hasn't been approved yet. There's no separate reservation step; posting is the charge.

Content restrictions: title, instructions, and proof descriptions are automatically screened for prohibited wording (e.g. language explicitly asking freelancers to click ads) — a match rejects the post with ok: false. Some patterns are severe enough to ban the account outright, in that same response — the message doesn't distinguish the two.

Approval: a posted job goes straight to RUNNING only if your account has auto-approval enabled; otherwise it's created as PENDING_REVIEW and needs a member of our team to manually review and approve it before freelancers can pick it up. New accounts start without auto-approval. There's no fixed review time, though reviews are handled as quickly as we can get to them, and email notification on approval depends on your account's notification preferences — don't rely on an email arriving. To know reliably when it's approved, check the job's status via Get Job, or listen for the Job Status Changed webhook.

Job Cost & Fees (estimated): the total cost of a job is roughly num_tasks × task_value, plus an approval fee and a campaign fee — a percentage-based rate for most jobs, or the Power Jobs fee for jobs where task_value is $2 or higher — plus 3% of the total (minimum $1) if notify_followers is enabled. These rates are not fixed — they can vary per account and change over time. Your account's current rates are shown on the Pricing page. For the exact estimated cost of a specific job before posting it, send your request with test: 1 — the response will include an estimated_cost field calculated from your account's current rates, without creating the job or charging your balance.

SEO category jobs: jobs in a SEO category (category id starting with "10") currently cannot be posted targeting the west1, europe1, or europe2 zones. This also blocks adding positions, editing targeting, or restarting/resuming any older job that already has this combination. Separately, SEO-category jobs targeting the International zone (int) are not shown to freelancers in several Western countries — there's currently no reliable way to reach those countries for an SEO-category job via zone targeting.

Example request — Classic job (targets a zone)

        POST /api/jobs/post-job.php HTTP/1.1
        Host: sproutgigs.com
        Authorization: Basic dXNlcl9pZDphcGlfc2VjcmV0
        Content-Type: application/json

        {
          "zone_id": "int",
          "category_id": "0501",
          "title": "Sign up to ACME website",
          "instructions": [
              "visit the ACME website",
              "Create an account"
          ],
          "proofs": [
              {
                  "description": "Screenshot of your profile at ACME website",
                  "type": "screenshot"
              }
          ],
          "num_tasks": 25,
          "task_value": 0.10,
          "speed": 1000,
          "ttr": 7,
          "hold_time": 15,
          "watch_time": 0,
          "daily_tasks_limit": 0,
          "hourly_tasks_limit": 0
        }
      

Example request — List job (list_id instead of zone_id, no country/sex targeting)

        POST /api/jobs/post-job.php HTTP/1.1
        Host: sproutgigs.com
        Authorization: Basic dXNlcl9pZDphcGlfc2VjcmV0
        Content-Type: application/json

        {
          "list_id": 15237,
          "category_id": "0501",
          "title": "Sign up to ACME website",
          "instructions": [
              "visit the ACME website",
              "Create an account"
          ],
          "proofs": [
              {
                  "description": "Screenshot of your profile at ACME website",
                  "type": "screenshot"
              }
          ],
          "num_tasks": 25,
          "task_value": 0.10
        }
      

Example request — Express job (category_id starting with "01")

        POST /api/jobs/post-job.php HTTP/1.1
        Host: sproutgigs.com
        Authorization: Basic dXNlcl9pZDphcGlfc2VjcmV0
        Content-Type: application/json

        {
          "zone_id": "int",
          "category_id": "0101",
          "title": "Follow our page",
          "instructions": [
              "Visit the page and follow it"
          ],
          "proofs": [
              {
                  "description": "Screenshot showing you're following",
                  "type": "screenshot"
              }
          ],
          "num_tasks": 25,
          "task_value": 0.10
        }
      

The following fields can be added in the request body:

Attribute Type Required? Default Description
test integer no 0 Set this attribute to 1 if you are in development. The job will be validated but it will not be created. No costs will be charged from your spendable balance. The response will include an estimated_cost field with the total cost calculated from your account's current rates (see "Job cost & fees" above).
zone_id string conditionally required Zone ID to publish the job. Send exactly one of zone_id or list_id — never both, never neither. Use the zones and/or lists endpoints to get the list of zones and/or buyer lists. See the SEO category jobs note above for a targeting restriction that applies to some categories.
list_id int conditionally required List ID to publish the job. Send exactly one of zone_id or list_id — never both, never neither. Can be one of your own lists (Get Lists) or a public list from another buyer or from SproutGigs itself (Get Public Lists).
excluded_countries string array no List of countries codes to be excluded from the target zone. Use the zones endpoint to get a list of excludable countries for each zone. Capped at 10 countries, except for SEO category jobs (category id starting with "10"), which allow up to 20.
excluded_previous_job_ids string array no IDs of your own previous jobs whose freelancers should be excluded from this one. Any freelancer who was rated OK on any of the listed jobs won't see or be able to pick up this new job — useful to avoid repeat workers across similar jobs. Every ID must belong to a job you own; an unrecognized or not-yours ID rejects the whole request.
category_id string yes Category ID to publish the job. Use the categories endpoint to get the list of available categories. The category ID must be exactly what is returned in the category endpoint, respecting the leading zeroes that may exist. Category 9801 (qualification jobs — used to test/screen freelancers before inviting them to paid work) has extra rules: your account needs a prior deposit history, you can have at most 3 qualification jobs running at once, and num_tasks is capped at 1000.
title string yes Job title. Max of 255 characters.
notes string no Additional work notes for freelancers. Max of 512 characters.
instructions string array conditionally required List of instructions of expected work from freelancers. You may also include variables. Example: ["Visit website ABC", "Click the first post.", "Click the {{ORDINAL}} link from the top."]. Required unless dynamic_endpoint is provided. Combined instructions are limited to 5120 characters.
dynamic_endpoint string conditionally required URL of an endpoint that will be called at task start time to fetch live instructions for each freelancer. Required unless instructions is provided — the two are mutually exclusive.

When set, the instructions field is ignored. The endpoint must be a valid HTTPS URL and cannot exceed 2048 characters.

Your endpoint will receive a GET request with these query parameters: job_id, worker_id, task_id, ip, country.

The dynamic_instructions field in Get Job/Get Jobs reflects this: {"enabled": true, "endpoint": "<url>"} if set, {"enabled": false} (no endpoint key) otherwise — always one of these two shapes, never null.
variables object array no Nested object with the following attributes. Mandatory if a variable has been informed in the instructions.

Attribute Type Required? Default Description
name string yes Variable name as informed in the instructions without the braces {{}}. For example, if you have added a variable in the instructions like {{URL}}, just use "URL" as the name of the variable.
values array yes Variable values. It must have more than 1 value and less than 1000. If there are more variables, the number of values in all variables must be the same.

num_tasks is split as evenly as possible across each variable value row (any remainder goes to the first rows) — it's not a separate count per value, so plan num_tasks with the number of value rows in mind.

{{PW_ID}} and {{JOB_ID}} are reserved system macros — you don't need to (and cannot) declare them as variables. They're automatically replaced with the freelancer's ID and this job's ID wherever they appear in the instructions, which is useful for building trackable callback URLs. See Auto-rating with PCODE for a worked example.

proofs object array yes Nested object with the following attributes. A max of 4 proofs can be required.

Attribute Type Required? Default Description
type string yes Proof type. Possible values: date, datetime, email, list, number, screenshot, text, url. For list type, also provide options (array of 2–10 strings) and optionally multiple (boolean, default false). For datetime, the submitted value is stored in format YYYY-MM-DD HH:mm (worker local time); date is stored as YYYY-MM-DD. Each screenshot proof raises the minimum task_value by $0.05 ($0.04 for category 37) — this stacks for however many screenshot proofs you add, up to the overall 4-proof limit noted above. This floor only applies if ttr is left at its default — an extended ttr (see below) applies its own, separate minimum instead of stacking with the screenshot one, regardless of how many screenshot proofs the job has. For text proofs, avoid using the word "screenshot" (or close variations) in the description — it will be rejected. text, email, url, date, and datetime proofs are limited to 2000 characters; nickname to 50. screenshot uploads are limited to 2MB and must be PNG, JPG, GIF, or HEIC/HEIF (HEIC/HEIF is automatically converted to JPG). url proofs must start with http:// or https://. For jobs in category 05 (Emails) whose title or proof description mentions "gmail", at least one email proof submitted must be a real @gmail.com/@googlemail.com address — this check is triggered automatically by your job's wording, not a field you set.
description string yes Proof description. What is required from freelancers to prove they have completed the task.
options string array list only Required when type is list. Array of 2–10 option strings that freelancers can select.
multiple boolean no false Only for type list. When true, freelancers can select multiple options.
challenges object array no Nested object with the following attributes. A max of 3 challenges can be set up. Challenges cannot be combined with System Verify (autorate V or V+R) — the request will be rejected if both are set. Use autorate NO (manual rating) to use challenges.

An incorrect answer automatically rates the task NOT_OK (and, depending on challenge_action, can block the freelancer from your future jobs) — write clear, unambiguous questions and answers so freelancers aren't penalized by a reasonable but differently-worded answer. Answer matching is lenient rather than an exact match, so don't rely on it to reject anything beyond a genuinely wrong answer.

Attribute Type Required? Default Description
question string yes Challenge question that will be displayed to users.
answer string yes The correct answer to the challenge question to be verified against the answer from freelancers.
challenge_action string no Action to be taken when freelancer answer the challenge incorrectly. Possible values are rate_nok, to rate the task NOT_OK, and rate_nok_block, to rate the task NOT_OK and block the freelancer from future jobs. Required if there are challenges set up.
num_tasks int yes Number of tasks to be performed by freelancers. There's no default — omitting or sending 0 is rejected. The minimum varies per category — check min_workers on the Get Categories endpoint.
workers_level string no starter Target a minimum level of freelancers. Possible values are "starter", "advanced" and "expert". The minimum task_value allowed is 25% higher for "advanced" and 50% higher for "expert" (see the Get Categories endpoint for the base minimum per category/zone).
workers_sex string no all Target freelancers sex. Possible values are "all", "f", "m". Not applicable to list jobs.
workers_device string no all Target freelancers by device. Possible values are "all", "desktop", "mobile" (mobile includes tablets).
workers_max_tasks int no 1 Number of tasks that the same freelancer can submit. It can range from 1 to 60 — but a value above 1 is rejected with ok: false unless workers_level is "advanced" or "expert" (it defaults to "starter" if omitted).
task_value float yes Amount each freelancer will earn if the task is rated OK.
speed int no 1000 Speed which the job is displayed to freelancers. From 1-1000 (1 is slow, 1000 is fast-normal. Each page refresh generates a random number. All job speed setting numbers above this random number are shown. A speed of 10 or even 100, the probability of showing up is really low.)
start_time string no 00:00 Start time for the job to be available to freelancers. Use UTC time in the format `HH:mm`, where `HH` ranges from 00 to 24 and `mm` ranges from 00 to 59
end_time int no 24:00 End time for the job to be available to freelancers. Use UTC time in the format `HH:mm`, where `HH` ranges from 00 to 24 and `mm` ranges from 00 to 59
ttr int no 7 Number of days the buyer has to rate the task before it is auto rated OK by the system. It ranges from 1 to 90 days — a value outside that range isn't rejected: too low falls back to the default of 7, too high is capped at 90. Setting a ttr above the default of 7 days raises the minimum task_value in tiers (roughly +$0.25/+$0.50/+$0.75 per 30-day range above the default, scaled by workers_level) — this replaces, rather than stacks with, the screenshot-proof price floor described above. Call the endpoint with test: 1 to get the exact minimum for your configuration.
autorate string no NO Used to let the system auto rate tasks based on the PCODE submitted by the freelancers. Possible values are NO, where the system will not do anything and all rating will be left for the buyer. V, where the system will verify if the freelancer has submitted the correct PCODE but will not rate the task. V+R, where the system will verify and auto rate the task OK if the freelancer submitted the correct PCODE. To learn more about PCODE, visit Auto-rating with PCODE. Cannot be set to V or V+R if challenges are configured on the job.
pause_after_approval int no 0 Used to immediately pause the job after it's approved. Possible values are 0, to not pause it and 1, to pause it.
scheduled_start_at string no null Schedule an exact future date and time (UTC) for the job to automatically go live. Format: YYYY-MM-DD HH:mm:ss. Must be a future datetime. Leave blank or omit to go live immediately after approval. If set, the job will be paused after approval and will automatically go live at the scheduled time.
hold_time int no 15 The number of minutes a freelancer can hold a position before submitting the task. It ranges from 5 to 90.
hold_required int no 0 Require freelancers to hold the position before submitting the task. It's better used when the hold time is longer than 5 minutes. Only takes effect for List jobs (list_id) — sending it on a Classic or Express job (zone_id) has no effect.
watch_time int no 0 Minimum time (in minutes) the freelancer must spend on the task before submitting. The task cannot be submitted before the timer ends. Set to 0 to turn off. Cannot exceed hold_time. Only available for accounts with auto-approval enabled.
distribution int no Maximum percentage of tasks done by freelancers in a single country. Value can range from 25 to 100. For example, if a job has 100 positions and the max distribution is 50%, 50 tasks could be done by freelancers in the same country and the other 50 tasks must be done by freelancers in a different country. When omitted, the default is not a fixed value — it depends on the target zone and, for zones with multiple countries, on how many countries are included.
daily_tasks_limit int no 0 Maximum number of tasks that can be submitted per day (UTC). Set to 0 for no limit.
hourly_tasks_limit int no 0 Maximum number of tasks that can be submitted per hour (UTC). Set to 0 for no limit.
notify_followers int no 0 Freelancers that follow you will receive a notification about the new job posted. It costs 3% of the total job cost with a minimum of $1.
premium_amount float no 0 Feature the job at creation time — same bidding mechanism as the Feature Job endpoint, just set upfront instead of afterward. The job's position depends on the amount set by other buyers at the time. Minimum amount is $2.00 — anything below that is treated as not featuring the job at all, with no upper limit.
premium_days integer no 1 Period in days to feature the job. It will get renewed every 24 hours if the job is still running and your account has enough funds.
premium_credit boolean no false If true, features the job using one of your feature-job credits instead of charging premium_amount — rejected if you don't have any. See Feature Job for how credits are earned.

Example response

        {
          "ok": true,
          "url": "https://sproutgigs.com/employer/campaign-details.php?Id=JOB_ID",
          "message": "Job posted successfully"
        }
      

Example response with test: 1

        {
          "ok": true,
          "test": true,
          "message": "job posted successfully",
          "estimated_cost": "12.50"
        }
      

Rate Multiple Tasks Endpoint

Rate up to 1000 tasks of a job in one request. See the Rate Single Task endpoint for what each rating option does — the same rules apply per task here. Doesn't work while the job is PAUSED_ADMIN, PENDING_REVIEW, or PENDING_RESTART — checked both up front and again before each individual task, so if enough NOT_OK ratings earlier in the same batch auto-pause the job partway through, later tasks in that same request can fail with this message even though the request itself was accepted.

        POST https://sproutgigs.com/api/jobs/rate-multiple-tasks.php

Example request

        POST /api/jobs/rate-multiple-tasks.php HTTP/1.1
        Host: sproutgigs.com
        Authorization: Basic dXNlcl9pZDphcGlfc2VjcmV0
        Content-Type: application/json

        {
          "job_id": "fc7b3bd10d08",
          "tasks": [
            {
                "id": "1416896140ecb7",
                "rating": "ok",
                "satisfaction": "good",
                "comment": "great job!",
                "list_id": 0,
                "block_worker": false,
                "bonus": 0.0,
                "remove_from_list": false
            },

            ...

            {
                "id": "158004285a3523",
                "rating": "nok",
                "satisfaction": "incorrect",
                "comment": "wrong answer",
                "list_id": 0,
                "block_worker": false,
                "bonus": 0.0,
                "remove_from_list": true
            }
          ]
        }
      

The following fields can be added in the request body:

Attribute Type Required? Default Description
job_id string yes Id of the Job.
tasks object array yes Nested object with the following attributes.

Attribute Type Required? Default Description
id string yes Id of the task to be rated.
rating string yes Task rating. Possible values are: ok, not_ok, revise
satisfaction string no Your satisfaction with the task. Possible values are: excellent, good, ok (if rating is ok), or: incorrect, spam, dupe (if rating is not_ok). A value that doesn't match the current rating (e.g. excellent on a not_ok rating) is silently discarded rather than rejected — the rating still succeeds, just without that field recorded.
comment string no Task comments. Required if rating is not_ok or revise. Max 1024 characters. Same content restrictions as job title/instructions apply — a match rejects the whole rating.
list_id int no 0 Inform the id of a custom list in case you want to add the freelancer to it.
block_worker boolean no false Block this freelancer platform-wide — same effect as Block Freelancers: they're barred from working for you again and removed from every list you own, not just this job's list. Takes priority over remove_from_list below (redundant once blocking already removes them everywhere).
bonus float no 0.0 Bonus amount to be sent to the freelancer. Must be between 10% and 50% of the task's task_value — an out-of-range amount is rejected. A commission is also charged on top of the bonus itself.
remove_from_list boolean no false Remove the freelancer from the current job's list only (custom lists only). Ignored if block_worker is also true — blocking already removes them from every list, this job's included.

Example response

        {
          "tasks": [
            {
                "id": "1416896140ecb7",
                "ok": true,
                "message": "Task rated successfully."
            },

            ...

            {
                "id": "158004285a3523",
                "ok": false,
                "message": "Task cannot be rated."
            }
          ]
        }
      

Rate Single Task Endpoint

Rate a submitted task OK (Satisfied — pays the freelancer task_value, plus an optional bonus), NOT_OK (rejected — requires a task_comment, and optionally block_worker or remove_from_list), or REVISE (send it back to the freelancer to fix, also requires a comment; not available for qualification jobs or on declined/blocked jobs, and only up to twice per task — a third REVISE on the same task is rejected). If you don't rate a task before its job's TTR window elapses, it's automatically rated OK. Doesn't work while the job is PAUSED_ADMIN, PENDING_REVIEW, or PENDING_RESTART. Rating a task NOT_OK frees up the position it held — this can bring a PAUSED_SYSTEM job back to RUNNING on its own (unless the job is an SEO-category job targeting west1/europe1/europe2 — see the note on Post Job, that combination stays paused), and if too many of a job's ratings come back NOT_OK, the job can be auto-paused (PAUSED_ADMIN) for review. If list_id or remove_from_list can't be applied (e.g. the list is full, or is one of the autogenerated: true ones), the rating itself still goes through — the response includes a list_warning field explaining what went wrong with the list update specifically. No list_warning means the list update (if any was requested) succeeded. You can also reverse a mistaken NOT_OK back to OK on the same task (the reverse direction is not allowed). If the job is still RUNNING or PAUSED, this costs nothing extra. If the job has already reached FINISHED or PAUSED_SYSTEM, though, the position this task held is no longer open to reclaim — reversing it re-charges you task_value plus commission, same as paying for a new task, and is rejected with ok: false if your balance can't cover it.

Rating a task NOT_OK also affects how quickly that freelancer can submit their next task — across all jobs, not just this one — by adding a short delay before their next submission is accepted; rating OK shortens it slightly instead. Reversing a NOT_OK to OK reverts this too.

        POST https://sproutgigs.com/api/jobs/rate-single-task.php

Example request

        POST /api/jobs/rate-single-task.php HTTP/1.1
        Host: sproutgigs.com
        Authorization: Basic dXNlcl9pZDphcGlfc2VjcmV0
        Content-Type: application/json

        {
          "job_id": "fc7b3bd10d08",
          "task_id": "1416896140ecb7",
          "task_rating": "ok",
          "task_satisfaction": "good",
          "task_comment": "great job!",
          "list_id": 0,
          "block_worker": false,
          "task_bonus": 0.0,
          "remove_from_list": false
        }
      

The following fields can be added in the request body:

Attribute Type Required? Default Description
task_id string yes Id of the task to be rated.
job_id string yes Id of the Job.
task_rating string yes Task rating. Possible values are: ok, not_ok, revise
task_satisfaction string no Your satisfaction with the task. Possible values are: excellent, good, ok (if rating is ok), or: incorrect, spam, dupe (if rating is not_ok). A value that doesn't match the current rating (e.g. excellent on a not_ok rating) is silently discarded rather than rejected — the rating still succeeds, just without that field recorded.
task_comment string no Task comments. Required if task_rating is not_ok or revise. Max 1024 characters. Same content restrictions as job title/instructions apply — a match rejects the whole rating.
list_id int no 0 Inform the id of a custom list in case you want to add the freelancer to it.
block_worker boolean no false Block this freelancer platform-wide — same effect as Block Freelancers: they're barred from working for you again and removed from every list you own, not just this job's list. Takes priority over remove_from_list below (redundant once blocking already removes them everywhere).
task_bonus float no 0.0 Bonus amount to be sent to the freelancer. Must be between 10% and 50% of the task's task_value — an out-of-range amount is rejected. A commission is also charged on top of the bonus itself.
remove_from_list boolean no false Remove the freelancer from the current job's list only (custom lists only). Ignored if block_worker is also true — blocking already removes them from every list, this job's included.

Example response

        {
          "ok": true,
          "message": "Task rated successfully."
        }
      

Restart Job Endpoint

Restart a FINISHED job to run it again — re-charges you for positions (including previously unfilled ones) and may send the job back for review depending on your account. Use Resume Job instead for a job that's merely PAUSED.

        POST https://sproutgigs.com/api/jobs/job-restart.php

Example request

        POST /api/jobs/job-restart.php HTTP/1.1
        Host: sproutgigs.com
        Authorization: Basic dXNlcl9pZDphcGlfc2VjcmV0
        Content-Type: application/json

        {
          "job_id": "fc7b3bd10d08",
          "positions": 10
        }
      

The following fields can be added in the request body:

Attribute Type Required? Default Description
job_id string yes Id of the job to be restarted.
positions int no Number of positions to add in that job. A finished job that already had every position filled requires at least 1 new position here — restarting it with nothing to charge for is rejected.
scheduled_start_at string no null Schedule an exact future date and time (UTC) for the job to automatically go live. Format: YYYY-MM-DD HH:mm:ss. Must be a future datetime. Leave blank or omit to go live immediately after approval. If set, the job will be kept paused after approval and will automatically go live at the scheduled time.

Example response

        {
          "ok": true,
          "notice": "job restarted successfully"
        }
      

Resume Job Endpoint

Resume a PAUSED job — no charge involved. Use Restart Job instead if the job has already reached FINISHED. If this is a list-targeted job whose initial "new job" notification never went out (e.g. it started paused because of pause_after_approval or a future-dated scheduled_start_at), resuming it for the first time sends that notification to every member of the list — same as it would have at creation time.

        POST https://sproutgigs.com/api/jobs/job-resume.php

Example request

        POST /api/jobs/job-resume.php HTTP/1.1
        Host: sproutgigs.com
        Authorization: Basic dXNlcl9pZDphcGlfc2VjcmV0
        Content-Type: application/json

        {
          "job_id": "fc7b3bd10d08"
        }
      

The following fields can be added in the request body:

Attribute Type Required? Default Description
job_id string yes Id of the job to be resumed.
scheduled_start_at string no null Schedule an exact future date and time (UTC) for the job to automatically go live. Format: YYYY-MM-DD HH:mm:ss. Must be a future datetime. Leave blank or omit to go live immediately. If set, the job will be kept paused and will automatically go live at the scheduled time.

Example response

        {
          "ok": true
        }
      

Set Speed Endpoint

Set the job's speed (1-1000) — this does not affect ranking position, only how often the job is included when freelancers load the job list. See How Job Ranking Works for the exact mechanics.

        POST https://sproutgigs.com/api/jobs/set-speed.php

Example request

        POST /api/jobs/set-speed.php HTTP/1.1
        Host: sproutgigs.com
        Authorization: Basic dXNlcl9pZDphcGlfc2VjcmV0
        Content-Type: application/json

        {
          "job_id": "fc7b3bd10d08",
          "speed": 800
        }
      

The following fields can be added in the request body:

Attribute Type Required? Default Description
job_id string yes Id of the job you want to set the new speed for.
speed int no 1000 Speed of the job. From 1 to 1000.

Example response

        {
          "ok": true,
          "message": "Job speed updated successfully."
        }
      

Set TTR Endpoint

Lower the job's time to rate (TTR) — the deadline before an unrated task is automatically marked OK. This endpoint can only decrease the current value, not increase it.

        POST https://sproutgigs.com/api/jobs/set-ttr.php

Example request

        POST /api/jobs/set-ttr.php HTTP/1.1
        Host: sproutgigs.com
        Authorization: Basic dXNlcl9pZDphcGlfc2VjcmV0
        Content-Type: application/json

        {
          "job_id": "fc7b3bd10d08",
          "ttr": 3
        }
      

The following fields can be added in the request body:

Attribute Type Required? Default Description
job_id string yes Id of the job you want to set the new TTR for.
ttr int no 7 Time to rate of the job. From 1 to 90 — a value outside that range isn't rejected: too low falls back to the default of 7, too high is capped at 90. This endpoint can only decrease the current TTR — a value that isn't strictly lower than the job's current TTR is rejected with ok: false, not silently ignored.

Example response

        {
          "ok": true,
          "message": "Job time to rate (TTR) updated successfully."
        }
      

Set Daily Tasks Limit Endpoint

Set the maximum number of tasks that can be submitted per day (UTC) for a job. Set to 0 for no limit.

        POST https://sproutgigs.com/api/jobs/set-daily-tasks-limit.php

Example request

        POST /api/jobs/set-daily-tasks-limit.php HTTP/1.1
        Host: sproutgigs.com
        Authorization: Basic dXNlcl9pZDphcGlfc2VjcmV0
        Content-Type: application/json

        {
          "job_id": "fc7b3bd10d08",
          "daily_tasks_limit": 50
        }
      

The following fields can be added in the request body:

Attribute Type Required? Default Description
job_id string yes Id of the job you want to set the daily tasks limit for.
daily_tasks_limit int no 0 Maximum number of tasks that can be submitted per day (UTC). Set to 0 for no limit.

Example response

        {
          "ok": true,
          "message": "Job daily tasks limit updated successfully."
        }
      

Set Hourly Tasks Limit Endpoint

Set the maximum number of tasks that can be submitted per hour (UTC) for a job. Set to 0 for no limit.

        POST https://sproutgigs.com/api/jobs/set-hourly-tasks-limit.php

Example request

        POST /api/jobs/set-hourly-tasks-limit.php HTTP/1.1
        Host: sproutgigs.com
        Authorization: Basic dXNlcl9pZDphcGlfc2VjcmV0
        Content-Type: application/json

        {
          "job_id": "fc7b3bd10d08",
          "hourly_tasks_limit": 10
        }
      

The following fields can be added in the request body:

Attribute Type Required? Default Description
job_id string yes Id of the job you want to set the hourly tasks limit for.
hourly_tasks_limit int yes 0 Maximum number of tasks that can be submitted per hour (UTC). Set to 0 for no limit.

Example response

        {
          "ok": true,
          "message": "Job hourly tasks limit updated successfully."
        }
      

Set Distribution Endpoint

Cap the percentage of a job's tasks that can be done by freelancers from any single country — useful to spread results across a broader set of countries instead of letting one dominate.

        POST https://sproutgigs.com/api/jobs/set-distribution.php

Example request

        POST /api/jobs/set-distribution.php HTTP/1.1
        Host: sproutgigs.com
        Authorization: Basic dXNlcl9pZDphcGlfc2VjcmV0
        Content-Type: application/json

        {
          "job_id": "fc7b3bd10d08",
          "distribution": 50
        }
      

The following fields can be added in the request body:

Attribute Type Required? Default Description
job_id string yes Id of the job you want to set the distribution for.
distribution int yes Maximum percentage of tasks done by freelancers from a single country. From 10 to 100 — note this is a lower floor than the distribution field on Post Job, which only goes down to 25. Example: 100 positions + 50% distribution = 50 max tasks from the same country.

Example response

        {
          "ok": true,
          "message": "Job distribution updated successfully."
        }
      

A couple of things worth knowing about how this cap is actually applied: it's enforced per-request as freelancers submit tasks, not by pre-splitting positions across countries up front — so early in a job's life a single country can still temporarily exceed the cap until enough tasks come in from elsewhere to balance it out. Separately, jobs in the international SEO categories are hidden from freelancers in a set of western countries regardless of your distribution setting — that filter isn't something this field controls.

Stop Job Endpoint

Stop a job for good — unlike pausing, this moves the job to FINISHED (only Restart Job can bring it back). Works on a job that's RUNNING, PAUSED, or PAUSED_SYSTEM. Refunds only the unused positions (available positions minus positions already filled), plus their proportional fee — it does not refund the approval fee or any Feature Job/notify_followers spend already committed for this job. If the job still has submitted-but-unrated tasks when you stop it, their cost isn't refunded and the job can't be archived until they're rated — either manually or by letting each task's TTR window auto-rate it OK.

        POST https://sproutgigs.com/api/jobs/job-stop.php

Example request

        POST /api/jobs/job-stop.php HTTP/1.1
        Host: sproutgigs.com
        Authorization: Basic dXNlcl9pZDphcGlfc2VjcmV0
        Content-Type: application/json

        {
          "job_id": "fc7b3bd10d08"
        }
      

The following fields can be added in the request body:

Attribute Type Required? Default Description
job_id string yes Id of the job to be stopped.

Example response

        {
          "ok": true,
          "message": "Job has stoped."
        }
      

Lists

Lists are named groups of freelancers you can target a job at directly, instead of targeting by zone — see list_id on Post Job. Your own lists are managed here and read back via Get Lists (that endpoint lives under Jobs since it's used when posting a list-targeted job); this section covers adding freelancers to a list and blocking/unblocking freelancers platform-wide, plus browsing public lists made available by other buyers or by SproutGigs itself. Some of your lists may be autogenerated: true — maintained automatically by SproutGigs rather than by you — and reject any attempt to add freelancers to them manually. One such list, named along the lines of "Freelancers you rated Satisfied," is created automatically the first time you rate a task OK and grows in near real time as you rate more tasks OK — useful as a ready-made list_id if you want to target your best-performing freelancers without building a list by hand. There's currently no API endpoint to create a brand-new custom list from scratch (only the website can do that) or to read back which freelancers are currently on a given list — the API can add to, remove from, and target a list, but not enumerate its members.

Making one of your lists public (website-only for now) can earn you a free Feature Job credit: every time another buyer runs a job targeting your public list that reaches at least 25 tasks with at least a 70% approval rate, it counts once toward your list — after 5 such qualifying jobs, you're credited one feature-job credit automatically.

Get Public Lists Endpoint

Browse public lists — made public by other buyers, or maintained by SproutGigs itself — which you can target with list_id when posting a job. Unlike your own private lists, these can be used by anyone. Returns id, name, worker count, category and the list owner (shown as "SproutGigs" for system-owned lists).

        GET https://sproutgigs.com/api/lists/get-public-lists.php

Example request

        GET /api/lists/get-public-lists.php HTTP/1.1
        Host: sproutgigs.com
        Authorization: Basic dXNlcl9pZDphcGlfc2VjcmV0
        Content-Type: application/json

        {
          "category_id": "65"
        }

The following fields can be added in the request body:

Attribute Type Required? Default Description
category_id string no 2-character category ID to filter the results. Omit to return lists from all categories. A value that isn't exactly 2 characters is treated the same as omitting it — no filter is applied, no error is raised. In practice, most public lists don't have a category assigned at all, so filtering by category_id will exclude them — omitting this parameter is the more reliable way to browse public lists today.

Example response

        [
          {
            "id": 1042,
            "name": "Top Writers",
            "workers": 150,
            "category_name": "Write an Article",
            "owner": "john_doe"
          }
        ]
      

Add Freelancers Endpoint

Add one or more freelancers to a custom list of yours. Invalid freelancers and freelancers banned platform-wide will not be added — this does not check your own Block Freelancers list, so a freelancer you've blocked can still be added here unless you unblock and re-block them, or remove them from the list separately. A list can hold at most 10,000 freelancers. Rejected entirely if the list is one of the autogenerated: true ones from Get Lists — those are maintained by SproutGigs, not by you.

        POST https://sproutgigs.com/api/lists/add-workers.php

Example request

        POST /api/lists/add-workers.php HTTP/1.1
        Host: sproutgigs.com
        Authorization: Basic dXNlcl9pZDphcGlfc2VjcmV0
        Content-Type: application/json

        {
          "list_id": 15237,
          "workers": ["0de178af", "ffcc1278", "abcd0129"]
        }
      

The following fields can be added in the request body:

Attribute Type Required? Default Description
list_id int yes Id of the list you want to add the freelancers.
workers string array yes List of freelancer ids to be added to the custom list. A list can have a maximum of 10,000 freelancers.

Example response

        {
          "ok": true,
          "message": "Freelancers added to the list successfully."
        }
      

Block Freelancers Endpoint

Block one or more freelancers from working for you — this only affects your own lists and notifications, it doesn't cancel anything they're already working on. Blocked freelancers are removed from all of your lists and won't be notified about your future jobs.

        POST https://sproutgigs.com/api/lists/block-workers.php

Example request

        POST /api/lists/block-workers.php HTTP/1.1
        Host: sproutgigs.com
        Authorization: Basic dXNlcl9pZDphcGlfc2VjcmV0
        Content-Type: application/json

        {
          "workers": ["0de178af", "ffcc1278", "abcd0129"]
        }
      

The following fields can be added in the request body:

Attribute Type Required? Default Description
workers string array yes List of freelancer ids to be blocked.

Example response

        {
          "ok": true,
          "message": "Freelancers blocked and removed from all lists successfully."
        }
      

Unblock Freelancers Endpoint

Reverse a block from Block Freelancers — the freelancer can work for you and be notified about your jobs again (they won't be automatically re-added to any list they were removed from).

        POST https://sproutgigs.com/api/lists/unblock-workers.php

Example request

        POST /api/lists/unblock-workers.php HTTP/1.1
        Host: sproutgigs.com
        Authorization: Basic dXNlcl9pZDphcGlfc2VjcmV0
        Content-Type: application/json

        {
          "workers": ["0de178af", "ffcc1278", "abcd0129"]
        }
      

The following fields can be added in the request body:

Attribute Type Required? Default Description
workers string array yes List of freelancer ids to be unblocked.

Example response

        {
          "ok": true,
          "message": "Freelancers unblocked successfully."
        }
      

Profiles

Get information about users.

Get Profile Endpoint

Get a user's country and freelancer level — user_id isn't restricted to your own account, so you can also use this to look up a gig seller before hiring them. This does not return fee or pricing information — see the Pricing page or the "Job cost & fees" note on the Post Job endpoint for that.

        GET https://sproutgigs.com/api/profiles/get-profile.php?user_id=1234abcd

Example request

        GET /api/profiles/get-profile.php?user_id=1234abcd HTTP/1.1
        Host: sproutgigs.com
        Authorization: Basic dXNlcl9pZDphcGlfc2VjcmV0
        Content-Type: application/json
      

Example response

        {
          "ok": true,
          "profile": {
            "id": "1234abcd",
            "country_code": "us",
            "country_name": "United States",
            "worker_level": "starter"
          }
        }
      

Users

Get information about your user.

Balances Endpoint

Get your account balances: spendable is your deposited funds available to fund jobs, and earned is money you've earned as a freelancer (withdrawable once at or above $5.00). A single account can have both if it's used to both post and complete work. All balances, job costs, and fees are in USD — there's no currency conversion anywhere on the platform.

        GET https://sproutgigs.com/api/users/get-balances.php

Example request

        GET /api/users/get-balances.php HTTP/1.1
        Host: sproutgigs.com
        Authorization: Basic dXNlcl9pZDphcGlfc2VjcmV0
        Content-Type: application/json
      

Example response

        {
          "earned": "0.4200",
          "spendable": "3.3482"
        }
      

Webhooks

Get notified when certain events happen. You can manage your webhook subscription either from Account Settings on the website, or with the endpoints below — both act on the same subscription, there isn't a separate "API-only" one. There's a single URL per account, shared across whichever events you subscribe to (not one URL per event).

Your url must be a public HTTPS address — plain HTTP and addresses that resolve to a private/internal network aren't accepted.

Treat webhooks as best-effort, not guaranteed delivery: each event is retried for up to 24 hours if your endpoint doesn't return a 200, then dropped permanently — there's no way to see or replay events that were dropped this way. If your endpoint has downtime longer than that, reconcile by polling Get Job or Get Unrated Tasks afterward rather than assuming you received everything.

Verifying Webhook Signatures

Every webhook delivery includes an X-Sproutgigs-Signature header, in the format sha256=<hex-encoded HMAC-SHA256>, computed over the raw request body using your webhook secret. The full value is only ever returned once — by Set Webhook (the first time you call it) or Rotate Webhook Secret — and from Account Settings right after generating or rotating it there. Get Webhook only ever returns a masked version, for confirming which secret is configured, not for retrieving it. If you lose it, rotate to get a new one. Verify the signature before trusting a delivery — anyone who learns your webhook URL can otherwise send fake postbacks to it. Recompute the HMAC over the exact raw body you received (not a re-serialized version of the parsed JSON, which can produce a different byte sequence) and compare it to the header using a constant-time comparison:

        // Node.js example
        const crypto = require('crypto');

        function isValidSignature(rawBody, signatureHeader, secret) {
          const expected = crypto.createHmac('sha256', secret).update(rawBody).digest('hex');
          const received = signatureHeader.replace('sha256=', '');
          return crypto.timingSafeEqual(Buffer.from(expected), Buffer.from(received));
        }
      

Treat the secret like any other credential — don't expose it client-side or commit it to a public repository.

Delete Webhook Endpoint new

Remove your webhook subscription entirely — unsubscribes from all events. To unsubscribe from only some events, use Set Webhook instead with the remaining events you want to keep.

        POST https://sproutgigs.com/api/webhooks/delete-webhook.php

Example request

        POST /api/webhooks/delete-webhook.php HTTP/1.1
        Host: sproutgigs.com
        Authorization: Basic dXNlcl9pZDphcGlfc2VjcmV0
      

Example response

        {
          "ok": true,
          "message": "Webhook removed successfully."
        }
      

Receive a postback when a job posted via Feature Job stops being featured, either because the featured period has run its course or because it was ended early (job no longer running, or insufficient funds to renew it). It runs every minute and will send the list of jobs that stopped being featured in that period. In case the URL defined does not return a 200 HTTP code response, the system will retry sending the list of job ids every 5 minutes for 24 hours. After that, it will stop trying to send the job ids.

The following fields will be sent in the request body:

Attribute Type Description
event_type string Type of the event. Example: featured_job_ended
event_date string Date and time of the event. Example: 2023-04-12T14:30:00Z
event object array Nested object with the following attributes.

Attribute Type Description
job_id string Job id. Example: abc123dfae98
reason string Why the job stopped being featured. Possible values are: expired, job_not_running, insufficient_funds.
Example: expired

Example postback parameters sent:

        {
            "event_type": "featured_job_ended",
            "event_date": "2023-04-12T14:30:00Z",
            "event":
            [
                {
                    "job_id": "abc123dfae98",
                    "reason": "expired"
                },

                ...

                {
                    "job_id": "dcfbb9c972fd",
                    "reason": "insufficient_funds"
                }
            ]
        }
      

Transaction Created Endpoint

Receive a postback whenever a new transaction is recorded on your account (deposits, withdrawals, task earnings, campaign fees, bonuses, and any other balance-affecting event). It runs every minute and will send the list of transactions recorded in that period. Delivery may lag a short time behind when the transaction was actually recorded. In case the URL defined does not return a 200 HTTP code response, the system will retry sending the list of transactions every 5 minutes for 24 hours. After that, it will stop trying to send the transactions.

The following fields will be sent in the request body:

Attribute Type Description
event_type string Type of the event. Example: transaction_created
event_date string Date and time of the event. Example: 2026-08-27T14:30:00Z
event object array Nested object with the following attributes.

Attribute Type Description
transaction_id number Transaction id. Example: 649400769
amount string Transaction amount. Negative for debits, positive for credits. Example: 5.00000
type string Transaction type. Example: SJ_TASK_EARNED
status string Transaction status. Example: COMPLETED
description string Human-readable description of the transaction. Example: Task earned $5.00
inserted_at string Date and time the transaction was recorded. Example: 2026-08-27T14:29:52Z

Example postback parameters sent:

        {
            "event_type": "transaction_created",
            "event_date": "2026-08-27T14:30:00Z",
            "event":
            [
                {
                    "transaction_id": 649400769,
                    "amount": "5.00000",
                    "type": "SJ_TASK_EARNED",
                    "status": "COMPLETED",
                    "description": "Task earned $5.00",
                    "inserted_at": "2026-08-27T14:29:52Z"
                },

                ...

                {
                    "transaction_id": 649400770,
                    "amount": "-2.50000",
                    "type": "SJ_CAMP_FEATURE",
                    "status": "COMPLETED",
                    "description": "Feature fee",
                    "inserted_at": "2026-08-27T14:29:58Z"
                }
            ]
        }
      

Get Webhook Endpoint new

Get your current webhook subscription: your registered URL, which events it's subscribed to, and a masked version of your webhook secret (e.g. a1b2c3d4...) so you can confirm which one is configured — not the full value (see Verifying Webhook Signatures for where to get that). If you haven't set one up, url and secret are null and events is empty.

        GET https://sproutgigs.com/api/webhooks/get-webhook.php

Example request

        GET /api/webhooks/get-webhook.php HTTP/1.1
        Host: sproutgigs.com
        Authorization: Basic dXNlcl9pZDphcGlfc2VjcmV0
      

Example response

        {
          "ok": true,
          "url": "https://example.com/webhooks/sproutgigs",
          "secret": "a1b2c3d4...",
          "events": ["job_status_changed", "tasks_submitted"]
        }
      

Job Status Changed Endpoint

Receive a postback when your job(s) status changes. It runs every minute and will send the list of status changes for each job in that period. In case the URL defined does not return a 200 HTTP code response, the system will retry sending the list of task ids every 5 minutes for 24 hours. After that, it will stop trying to send the status changes.

The following fields will be sent in the request body:

Attribute Type Description
event_type string Type of the event. Example: job_status_changed
event_date string Date and time of the event. Example: 2023-04-12T14:30:00Z
event object array Nested object with the following attributes.

Attribute Type Description
job_id string Job id. Example: abc123dfae98
changes object array Nested object with the following attributes.

Attribute Type Description
date string date and time of the status change. Example: 2023-04-12T14:29:30Z
status string Job status. Possible values are: running, paused, paused_admin, paused_system, pending_approval, pending_restart, pending_review, blocked, declined, finished.
Example: pending_review

Example postback parameters sent:

        {
            "event_type": "job_status_changed",
            "event_date": "2023-04-12T14:30:00Z",
            "event":
            [
                {
                    "job_id": "abc123dfae98",
                    "changes":
                    [
                        {
                            "date": "2023-04-12T14:26:10Z",
                            "status": "running"
                        },
                        {
                            "date": "2023-04-12T14:27:30Z",
                            "status": "paused"
                        },
                        {
                            "date": "2023-04-12T14:28:50Z",
                            "status": "finished"
                        }
                    ]
                },

                ...

                {
                    "job_id": "dcfbb9c972fd",
                    "changes":
                    [
                        {
                            "date": "2023-04-12T14:28:05Z",
                            "status": "pending_review"
                        }
                    ]
                },

                ...

                {
                    "job_id": "318ff8a16e05",
                    "changes":
                    [
                        {
                            "date": "2023-04-12T14:25:10Z",
                            "status": "pending_approval"
                        },
                        {
                            "date": "2023-04-12T14:26:15Z",
                            "status": "running"
                        },
                        {
                            "date": "2023-04-12T14:29:58Z",
                            "status": "finished"
                        }
                    ]
                }
            ]
        }
      

Rotate Webhook Secret Endpoint new

Generate a new webhook secret, invalidating the current one. Use this if you suspect your secret has leaked, or just want to refresh it — unlike Set Webhook, which preserves your existing secret, this always issues a new one. The new value is returned in full only in this response — see Verifying Webhook Signatures. Fails if you don't have a webhook URL configured yet.

        POST https://sproutgigs.com/api/webhooks/rotate-webhook-secret.php

Example request

        POST /api/webhooks/rotate-webhook-secret.php HTTP/1.1
        Host: sproutgigs.com
        Authorization: Basic dXNlcl9pZDphcGlfc2VjcmV0
      

Example response

        {
          "ok": true,
          "message": "Webhook secret rotated successfully.",
          "secret": "9f8e7d6c5b4a..."
        }
      

Set Webhook Endpoint new

Create or update your webhook subscription. This replaces the full subscription: events you omit from the list are unsubscribed, so always send the complete set of events you want active, not just the one you're adding. The response includes your webhook secret in full — generated the first time you call this, and left unchanged on later calls (e.g. adjusting which events you're subscribed to doesn't rotate it; use Rotate Webhook Secret for that). See Verifying Webhook Signatures.

        POST https://sproutgigs.com/api/webhooks/set-webhook.php

Example request

        POST /api/webhooks/set-webhook.php HTTP/1.1
        Host: sproutgigs.com
        Authorization: Basic dXNlcl9pZDphcGlfc2VjcmV0
        Content-Type: application/json

        {
          "url": "https://example.com/webhooks/sproutgigs",
          "events": ["job_status_changed", "tasks_submitted", "featured_job_ended", "transaction_created"]
        }
      

The following fields can be added in the request body:

Attribute Type Required? Default Description
url string yes Public HTTPS URL to receive postbacks. Applies to every event in events — there's no per-event URL.
events string array yes At least one of job_status_changed, tasks_submitted, featured_job_ended, transaction_created. Any of these not included is unsubscribed.

Example response

        {
          "ok": true,
          "message": "Webhook settings saved successfully.",
          "secret": "a1b2c3d4e5f6..."
        }
      

Submitted Tasks Endpoint

Receive a postback when freelancers submit tasks to your jobs — useful for triggering your own rating logic as soon as work comes in, instead of polling Get Unrated Tasks. It runs every minute and will send the list of task ids submitted for each job in that period. In case the URL defined does not return a 200 HTTP code response, the system will retry sending the list of task ids every 5 minutes for 24 hours. After that, it will stop trying to send the task ids.

The following fields will be sent in the request body:

Attribute Type Description
event_type string Type of the event. Example: tasks_submitted
event_date string Date and time of the event. Example: 2023-04-12T14:30:00Z
event object array Nested object with the following attributes.

Attribute Type Description
job_id string Job id. Example: abc123dfae98
task_ids string array List of submitted tasks. Example: ["99900012abcd1f", "99923817f2bce4", "99924617ab23df"]

Example postback parameters sent:

        {
            "event_type": "tasks_submitted",
            "event_date": "2023-04-12T14:30:00Z",
            "event":
            [
                {
                    "job_id": "abc123dfae98",
                    "task_ids":
                    [
                        "99900012abcd1f",
                        "99923817f2bce4",
                        "99924617ab23df"
                    ]
                },

                ...

                {
                    "job_id": "dcfbb9c972fd",
                    "task_ids":
                    [
                        "79968612554d5b"
                    ]
                },

                ...

                {
                    "job_id": "318ff8a16e05",
                    "task_ids":
                    [
                        "263868612554b4e",
                        "845396612554b5b",
                        "479584922554a9b"
                    ]
                }
            ]
        }