SproutGigs' API Documentation
Last updated at Jul 23, 2026
Contents
- Overview
- Authentication
- Rate Limit
- Errors
- Terms
- Gigs
-
Jobs
- How Job Ranking Works
- Job Status Values
- Power Jobs
- Add Positions
- Edit Targetingnew
- Feature Job
- Get Categories
- Get Job Analyticsnew
- Get Job
- Get Jobs
- Get Lists
- Get Predicted Position
- Get Rated Tasks
- Get Unrated Tasks
- Get Zones
- Pause Job
- Post Job
- Rate Multiple Tasks
- Rate Single Task
- Restart Job
- Resume Job
- Set Speed
- Set TTR
- Set Daily Tasks Limit
- Set Hourly Tasks Limit
- Set Distribution
- Stop Job
- Lists
- Profiles
- Users
- Webhooks
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
ttron 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 — seecategory_idon Post Job. - Power Job — a job whose
task_valueis $2 or more, which changes the fees on both sides. See Power Jobs. - System Verify — two of the three
autoratevalues, 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. Seeautorateon 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:
- Featured jobs (bought via a bid, see Get Predicted Position below) always sort first.
- 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.
- 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_approvalor a futurescheduled_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 futurescheduled_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_approvalor a futurescheduled_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 whenlist_idis omitted andcategory_iddoes not start with "01" (Express Jobs). - Express: a streamlined job type for quick, simple tasks. Triggered by using a
category_idthat 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_idinstead ofzone_id— country targeting andexcluded_countriesdon'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 yournotify_followerssetting. Unlike Classic/Express, the campaign fee here has a minimum dollar amount per task, not just a percentage — for lowtask_valuejobs, the effective fee can end up well above the plain percentage rate;test: 1will show the real number. If you send bothlist_idand an Expresscategory_id,list_idwins 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.
{{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.
|
|||||||||||||||||||||||||
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.
|
|||||||||||||||||||||||||
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.
|
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."
}
Featured Job Ended Endpoint
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.
|
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.
|
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.
|
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.
|
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"
]
}
]
}