[{"data":1,"prerenderedAt":1004},["ShallowReactive",2],{"/docs/jobs/jobcreator/api/server-exports":3,"/docs/jobs/jobcreator/api/server-exports-surround":990,"/docs/jobs/jobcreator/api/server-exports-implemented-suggestions":1003},{"id":4,"title":5,"body":6,"description":979,"extension":980,"head":981,"implementedSuggestions":981,"meta":982,"navigation":983,"path":985,"schemaOrg":981,"seo":986,"sitemap":987,"stem":988,"__hash__":989},"docs/1.docs/0.jobs/6.jobcreator/5.api/2.server-exports.md","Server exports",{"type":7,"value":8,"toc":967},"minimark",[9,35,40,134,137,256,259,335,344,348,403,409,489,497,501,559,562,606,614,618,632,644,648,703,709,713,797,813,817,876,883,887,902,910,914,924,932,936,963],[10,11,12,13,17,18,22,23,26,27,30,31,34],"p",{},"All calls on this page run in a ",[14,15,16],"strong",{},"server script"," and use ",[19,20,21],"code",{},"exports[\"sky_jobs_base\"]",". ",[19,24,25],{},"playerId"," means the online player's numeric server ID. ",[19,28,29],{},"jobName"," means the technical job name, such as ",[19,32,33],{},"sunrise_cafe",".",[36,37,39],"h2",{"id":38},"job-and-duty","Job and duty",[41,42,43,59],"table",{},[44,45,46],"thead",{},[47,48,49,53,56],"tr",{},[50,51,52],"th",{},"Export",[50,54,55],{},"Arguments",[50,57,58],{},"Returns",[60,61,62,83,102,115],"tbody",{},[47,63,64,70,73],{},[65,66,67],"td",{},[19,68,69],{},"getPlayerJobInfo(playerId)",[65,71,72],{},"Player server ID",[65,74,75,78,79,82],{},[19,76,77],{},"{ job, grade, gradeLabel, onDuty }",", or ",[19,80,81],{},"nil"," if unavailable",[47,84,85,90,92],{},[65,86,87],{},[19,88,89],{},"isPlayerOnDuty(playerId)",[65,91,72],{},[65,93,94,97,98,101],{},[19,95,96],{},"boolean","; ",[19,99,100],{},"false"," when off duty or not loaded",[47,103,104,109,112],{},[65,105,106],{},[19,107,108],{},"getOnDutyPlayers(jobName)",[65,110,111],{},"Technical job name",[65,113,114],{},"Array of on-duty player server IDs",[47,116,117,122,131],{},[65,118,119],{},[19,120,121],{},"setPlayerDuty(playerId, onDuty)",[65,123,124,125,128,129],{},"Player server ID and ",[19,126,127],{},"true"," / ",[19,130,100],{},[65,132,133],{},"Whether the resulting duty state matches the request",[10,135,136],{},"For example, restrict an external activity to on-duty cafe employees:",[138,139,145],"pre",{"className":140,"code":141,"filename":142,"language":143,"meta":144,"style":144},"language-lua shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","local job = exports[\"sky_jobs_base\"]:getPlayerJobInfo(playerId)\nif not job or job.job ~= \"sunrise_cafe\" or not job.onDuty then\n    return\nend\n\n-- Continue your cafe-only action here.\n","server.lua","lua","",[19,146,147,185,230,236,242,249],{"__ignoreMap":144},[148,149,152,156,160,163,166,169,173,175,178,182],"span",{"class":150,"line":151},"line",1,[148,153,155],{"class":154},"sMK4o","local",[148,157,159],{"class":158},"sTEyZ"," job ",[148,161,162],{"class":154},"=",[148,164,165],{"class":158}," exports[",[148,167,168],{"class":154},"\"",[148,170,172],{"class":171},"sfazB","sky_jobs_base",[148,174,168],{"class":154},[148,176,177],{"class":158},"]:",[148,179,181],{"class":180},"s2Zo4","getPlayerJobInfo",[148,183,184],{"class":158},"(playerId)\n",[148,186,188,192,195,197,200,203,207,210,213,215,218,220,222,224,227],{"class":150,"line":187},2,[148,189,191],{"class":190},"s7zQu","if",[148,193,194],{"class":154}," not",[148,196,159],{"class":158},[148,198,199],{"class":154},"or",[148,201,202],{"class":158}," job.",[148,204,206],{"class":205},"sBMFI","job",[148,208,209],{"class":154}," ~=",[148,211,212],{"class":154}," \"",[148,214,33],{"class":171},[148,216,217],{"class":154},"\" ",[148,219,199],{"class":154},[148,221,194],{"class":154},[148,223,202],{"class":158},[148,225,226],{"class":205},"onDuty",[148,228,229],{"class":190}," then\n",[148,231,233],{"class":150,"line":232},3,[148,234,235],{"class":190},"    return\n",[148,237,239],{"class":150,"line":238},4,[148,240,241],{"class":190},"end\n",[148,243,245],{"class":150,"line":244},5,[148,246,248],{"emptyLinePlaceholder":247},true,"\n",[148,250,252],{"class":150,"line":251},6,[148,253,255],{"class":254},"sHwdD","-- Continue your cafe-only action here.\n",[10,257,258],{},"Set duty from your own authorised clock-in or clock-out workflow:",[138,260,262],{"className":140,"code":261,"filename":142,"language":143,"meta":144,"style":144},"local changed = exports[\"sky_jobs_base\"]:setPlayerDuty(playerId, true) -- On duty\n-- Pass false to clock out.\nif not changed then\n    print(\"The requested duty state could not be applied\")\nend\n",[19,263,264,297,302,313,331],{"__ignoreMap":144},[148,265,266,268,271,273,275,277,279,281,283,286,289,291,294],{"class":150,"line":151},[148,267,155],{"class":154},[148,269,270],{"class":158}," changed ",[148,272,162],{"class":154},[148,274,165],{"class":158},[148,276,168],{"class":154},[148,278,172],{"class":171},[148,280,168],{"class":154},[148,282,177],{"class":158},[148,284,285],{"class":180},"setPlayerDuty",[148,287,288],{"class":158},"(playerId, ",[148,290,127],{"class":154},[148,292,293],{"class":158},") ",[148,295,296],{"class":254},"-- On duty\n",[148,298,299],{"class":150,"line":187},[148,300,301],{"class":254},"-- Pass false to clock out.\n",[148,303,304,306,308,310],{"class":150,"line":232},[148,305,191],{"class":190},[148,307,194],{"class":154},[148,309,270],{"class":158},[148,311,312],{"class":190},"then\n",[148,314,315,318,321,323,326,328],{"class":150,"line":238},[148,316,317],{"class":180},"    print",[148,319,320],{"class":158},"(",[148,322,168],{"class":154},[148,324,325],{"class":171},"The requested duty state could not be applied",[148,327,168],{"class":154},[148,329,330],{"class":158},")\n",[148,332,333],{"class":150,"line":244},[148,334,241],{"class":190},[10,336,337,338,343],{},"Use the authenticated player's server ID. See ",[339,340,342],"a",{"href":341},"/docs/base/jobs-base/server-exports/duty","Duty"," for the complete reference.",[36,345,347],{"id":346},"employees","Employees",[41,349,350,360],{},[44,351,352],{},[47,353,354,356,358],{},[50,355,52],{},[50,357,55],{},[50,359,58],{},[60,361,362,377,391],{},[47,363,364,369,372],{},[65,365,366],{},[19,367,368],{},"setJobMember(jobName, playerOrIdentifier, grade?)",[65,370,371],{},"Job, online server ID or offline character identifier, optional grade",[65,373,374],{},[19,375,376],{},"success, error?",[47,378,379,384,387],{},[65,380,381],{},[19,382,383],{},"removeJobMember(jobName, playerOrIdentifier)",[65,385,386],{},"Job and online server ID or offline character identifier",[65,388,389],{},[19,390,376],{},[47,392,393,398,400],{},[65,394,395],{},[19,396,397],{},"getJobMembers(jobName)",[65,399,111],{},[65,401,402],{},"Array of employee records",[10,404,405,408],{},[19,406,407],{},"setJobMember"," hires a player or changes an existing employee's grade. If the grade is omitted, it uses the job's lowest grade. Preserve actual grade numbers, including gaps.",[138,410,412],{"className":140,"code":411,"filename":142,"language":143,"meta":144,"style":144},"-- Run after your hiring system has authorised the application.\nlocal success, errorMessage = exports[\"sky_jobs_base\"]:setJobMember(\"sunrise_cafe\", playerId)\nif not success then\n    print((\"Hiring failed: %s\"):format(errorMessage))\nend\n",[19,413,414,419,451,462,485],{"__ignoreMap":144},[148,415,416],{"class":150,"line":151},[148,417,418],{"class":254},"-- Run after your hiring system has authorised the application.\n",[148,420,421,423,426,428,430,432,434,436,438,440,442,444,446,448],{"class":150,"line":187},[148,422,155],{"class":154},[148,424,425],{"class":158}," success, errorMessage ",[148,427,162],{"class":154},[148,429,165],{"class":158},[148,431,168],{"class":154},[148,433,172],{"class":171},[148,435,168],{"class":154},[148,437,177],{"class":158},[148,439,407],{"class":180},[148,441,320],{"class":158},[148,443,168],{"class":154},[148,445,33],{"class":171},[148,447,168],{"class":154},[148,449,450],{"class":158},", playerId)\n",[148,452,453,455,457,460],{"class":150,"line":232},[148,454,191],{"class":190},[148,456,194],{"class":154},[148,458,459],{"class":158}," success ",[148,461,312],{"class":190},[148,463,464,466,469,471,474,476,479,482],{"class":150,"line":238},[148,465,317],{"class":180},[148,467,468],{"class":158},"((",[148,470,168],{"class":154},[148,472,473],{"class":171},"Hiring failed: %s",[148,475,168],{"class":154},[148,477,478],{"class":158},"):",[148,480,481],{"class":180},"format",[148,483,484],{"class":158},"(errorMessage))\n",[148,486,487],{"class":150,"line":244},[148,488,241],{"class":190},[10,490,491,492,496],{},"See ",[339,493,495],{"href":494},"/docs/base/jobs-base/server-exports/players-members","Players & members"," for employee record fields and offline examples.",[36,498,500],{"id":499},"company-accounts","Company accounts",[41,502,503,513],{},[44,504,505],{},[47,506,507,509,511],{},[50,508,52],{},[50,510,55],{},[50,512,58],{},[60,514,515,531,546],{},[47,516,517,522,524],{},[65,518,519],{},[19,520,521],{},"getJobMoney(jobName)",[65,523,111],{},[65,525,526,527,530],{},"Current balance; ",[19,528,529],{},"0"," for an invalid job",[47,532,533,538,541],{},[65,534,535],{},[19,536,537],{},"addJobMoney(jobName, amount)",[65,539,540],{},"Job and positive whole amount",[65,542,543,544],{},"Success as ",[19,545,96],{},[47,547,548,553,555],{},[65,549,550],{},[19,551,552],{},"removeJobMoney(jobName, amount)",[65,554,540],{},[65,556,543,557],{},[19,558,96],{},[10,560,561],{},"For example, credit the company after a sale confirmed by your server script:",[138,563,565],{"className":140,"code":564,"filename":142,"language":143,"meta":144,"style":144},"local credited = exports[\"sky_jobs_base\"]:addJobMoney(\"sunrise_cafe\", 250)\n",[19,566,567],{"__ignoreMap":144},[148,568,569,571,574,576,578,580,582,584,586,589,591,593,595,597,600,604],{"class":150,"line":151},[148,570,155],{"class":154},[148,572,573],{"class":158}," credited ",[148,575,162],{"class":154},[148,577,165],{"class":158},[148,579,168],{"class":154},[148,581,172],{"class":171},[148,583,168],{"class":154},[148,585,177],{"class":158},[148,587,588],{"class":180},"addJobMoney",[148,590,320],{"class":158},[148,592,168],{"class":154},[148,594,33],{"class":171},[148,596,168],{"class":154},[148,598,599],{"class":158},", ",[148,601,603],{"class":602},"sbssI","250",[148,605,330],{"class":158},[10,607,608,609,613],{},"Check the result before confirming the transaction to the player. Calculate prices and rewards on the server. See ",[339,610,612],{"href":611},"/docs/base/jobs-base/server-exports/society-money","Society money"," for details.",[36,615,617],{"id":616},"billing","Billing",[10,619,620,621,624,625,628,629,34],{},"Use ",[19,622,623],{},"CreateInvoice(request)"," to issue an invoice from your own service workflow. It returns ",[19,626,627],{},"{ success = true, data = invoice }"," or ",[19,630,631],{},"{ success = false, error = code }",[10,633,634,635,639,640,643],{},"The ",[339,636,638],{"href":637},"/docs/base/jobs-base/server-exports/billing","Billing reference"," covers the full request, player/company recipients, payment modes, employee shares and the ",[19,641,642],{},"sky_jobs_base:billing:changed"," server event. Successful invoice creation does not mean the invoice was paid; check its payment status.",[36,645,647],{"id":646},"salary","Salary",[41,649,650,658],{},[44,651,652],{},[47,653,654,656],{},[50,655,52],{},[50,657,58],{},[60,659,660,671,682,693],{},[47,661,662,667],{},[65,663,664],{},[19,665,666],{},"pausePlayerSalary(playerId)",[65,668,669],{},[19,670,96],{},[47,672,673,678],{},[65,674,675],{},[19,676,677],{},"resumePlayerSalary(playerId)",[65,679,680],{},[19,681,96],{},[47,683,684,689],{},[65,685,686],{},[19,687,688],{},"isPlayerSalaryPaused(playerId)",[65,690,691],{},[19,692,96],{},[47,694,695,700],{},[65,696,697],{},[19,698,699],{},"getGradeSalary(jobName, grade)",[65,701,702],{},"Salary amount, interval in minutes",[10,704,705,706,34],{},"The pause state lasts until resumed or the player disconnects. See ",[339,707,647],{"href":708},"/docs/base/jobs-base/server-exports/salary",[36,710,712],{"id":711},"business-and-announcements","Business and announcements",[41,714,715,724],{},[44,716,717],{},[47,718,719,721],{},[50,720,52],{},[50,722,723],{},"Use",[60,725,726,738,748,758,768,783],{},[47,727,728,733],{},[65,729,730],{},[19,731,732],{},"GetBusinessState(jobName)",[65,734,735,736,82],{},"Read opening state and configured blip values; ",[19,737,81],{},[47,739,740,745],{},[65,741,742],{},[19,743,744],{},"GetBusinessContext(playerId)",[65,746,747],{},"Read the employee's authorised Business context",[47,749,750,755],{},[65,751,752],{},[19,753,754],{},"GetBusinessHistory(playerId, request)",[65,756,757],{},"Read announcement history for the employee's current job",[47,759,760,765],{},[65,761,762],{},[19,763,764],{},"SubmitBusinessAnnouncement(playerId, request)",[65,766,767],{},"Publish as an employee, with duty, permission and cooldown checks",[47,769,770,775],{},[65,771,772],{},[19,773,774],{},"SetBusinessOpen(jobName, open, message?, announce?, actorId?)",[65,776,777,778,628,780],{},"Change opening state from trusted server automation; ",[19,779,127],{},[19,781,782],{},"false, reason",[47,784,785,790],{},[65,786,787],{},[19,788,789],{},"BroadcastBusinessAnnouncement(jobName, kind, message?, actorId?)",[65,791,792,793,628,795],{},"Publish from trusted server automation; ",[19,794,127],{},[19,796,782],{},[10,798,799,800,803,804,807,808,812],{},"For player actions use ",[19,801,802],{},"SubmitBusinessAnnouncement"," with the authenticated handler's player ID. ",[19,805,806],{},"actorId"," on the automation exports only supplies history context. See ",[339,809,811],{"href":810},"/docs/base/jobs-base/server-exports/business","Business"," for request fields and error codes.",[36,814,816],{"id":815},"storage","Storage",[41,818,819,827],{},[44,820,821],{},[47,822,823,825],{},[50,824,52],{},[50,826,58],{},[60,828,829,842,853,865],{},[47,830,831,836],{},[65,832,833],{},[19,834,835],{},"GetStorageItemCount(stationId, jobName, grade, itemName)",[65,837,838,839,841],{},"Item count; ",[19,840,529],{}," if missing",[47,843,844,849],{},[65,845,846],{},[19,847,848],{},"RemoveStorageItem(stationId, jobName, grade, itemName, amount)",[65,850,851],{},[19,852,96],{},[47,854,855,860],{},[65,856,857],{},[19,858,859],{},"AddStorageItem(stationId, jobName, grade, itemName, amount, metadata?)",[65,861,862],{},[19,863,864],{},"success, reason?",[47,866,867,872],{},[65,868,869],{},[19,870,871],{},"AddStorageItems(stationId, jobName, grade, items)",[65,873,874],{},[19,875,864],{},[10,877,878,879,882],{},"Use the storage point's actual ID and authorise the supplied job/grade in your server script. These calls operate on shared station storage. See ",[339,880,816],{"href":881},"/docs/base/jobs-base/server-exports/storage"," for capacity, metadata and batch examples.",[36,884,886],{"id":885},"vehicles-and-deliveries","Vehicles and deliveries",[10,888,620,889,892,893,896,897,901],{},[19,890,891],{},"registerExternalVehicle(plate, jobName, model, netId?, ownerSource?, trunkCapacity?)"," after your external garage spawns a job vehicle, and ",[19,894,895],{},"unregisterExternalVehicle(plate)"," when it is removed. See ",[339,898,900],{"href":899},"/docs/base/jobs-base/server-exports/external-garage-integration","External garage integration"," for the complete spawn/cleanup example and accepted values.",[10,903,904,905,909],{},"For delivery scripts, use the ",[339,906,908],{"href":907},"/docs/base/jobs-base/server-exports/wholesale-orders","Wholesale orders"," exports to read, accept, reject and complete orders. Completing an order and depositing stock are separate operations; persist which delivery you completed before allowing it to run again.",[36,911,913],{"id":912},"permissions-and-events","Permissions and events",[10,915,916,919,920,34],{},[19,917,918],{},"hasJobPermission(playerId, permission, jobName?)"," checks a registered employee permission. Use the exact permission keys from ",[339,921,923],{"href":922},"/docs/base/jobs-base/server-exports/permissions","Permissions",[10,925,926,927,931],{},"React to job, duty, employee and invoice changes with ",[339,928,930],{"href":929},"/docs/base/jobs-base/events","Events",". These notifications let your integration update when something changes, without repeatedly polling exports.",[36,933,935],{"id":934},"more-server-integrations","More server integrations",[937,938,939,945,950,955,959],"ul",{},[940,941,942],"li",{},[339,943,944],{"href":810},"Business status and announcements",[940,946,947],{},[339,948,949],{"href":922},"Rank and unit permissions",[940,951,952],{},[339,953,954],{"href":708},"Salary settings",[940,956,957],{},[339,958,816],{"href":881},[940,960,961],{},[339,962,900],{"href":899},[964,965,966],"style",{},"html pre.shiki code .sMK4o, html code.shiki .sMK4o{--shiki-light:#39ADB5;--shiki-default:#89DDFF;--shiki-dark:#89DDFF}html pre.shiki code .sTEyZ, html code.shiki .sTEyZ{--shiki-light:#90A4AE;--shiki-default:#EEFFFF;--shiki-dark:#BABED8}html pre.shiki code .sfazB, html code.shiki .sfazB{--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D}html pre.shiki code .s2Zo4, html code.shiki .s2Zo4{--shiki-light:#6182B8;--shiki-default:#82AAFF;--shiki-dark:#82AAFF}html pre.shiki code .s7zQu, html code.shiki .s7zQu{--shiki-light:#39ADB5;--shiki-light-font-style:italic;--shiki-default:#89DDFF;--shiki-default-font-style:italic;--shiki-dark:#89DDFF;--shiki-dark-font-style:italic}html pre.shiki code .sBMFI, html code.shiki .sBMFI{--shiki-light:#E2931D;--shiki-default:#FFCB6B;--shiki-dark:#FFCB6B}html pre.shiki code .sHwdD, html code.shiki .sHwdD{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#546E7A;--shiki-default-font-style:italic;--shiki-dark:#676E95;--shiki-dark-font-style:italic}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .sbssI, html code.shiki .sbssI{--shiki-light:#F76D47;--shiki-default:#F78C6C;--shiki-dark:#F78C6C}",{"title":144,"searchDepth":151,"depth":187,"links":968},[969,970,971,972,973,974,975,976,977,978],{"id":38,"depth":187,"text":39},{"id":346,"depth":187,"text":347},{"id":499,"depth":187,"text":500},{"id":616,"depth":187,"text":617},{"id":646,"depth":187,"text":647},{"id":711,"depth":187,"text":712},{"id":815,"depth":187,"text":816},{"id":885,"depth":187,"text":886},{"id":912,"depth":187,"text":913},{"id":934,"depth":187,"text":935},"Read job data, manage employees and connect company payments from another server script.","md",null,{},{"icon":984},"i-lucide-server","/docs/jobs/jobcreator/api/server-exports",{"title":5,"description":979},{"loc":985},"1.docs/0.jobs/6.jobcreator/5.api/2.server-exports","fDrc8jA-RvQ2F9qHHallWhgDAI-w4N0IMQRL99FFZ6Q",[991,997],{"title":992,"path":993,"stem":994,"description":995,"icon":996,"children":-1},"API overview","/docs/jobs/jobcreator/api/overview","1.docs/0.jobs/6.jobcreator/5.api/1.overview","Find client exports, server exports and events for jobs, duty, employees, billing, storage and external menus.","i-lucide-waypoints",{"title":998,"path":999,"stem":1000,"description":1001,"icon":1002,"children":-1},"Client exports","/docs/jobs/jobcreator/api/client-exports","1.docs/0.jobs/6.jobcreator/5.api/3.client-exports","Open job menus and connect your own client interactions or radial menu.","i-lucide-monitor",[],1792936679582]