{"id":122,"date":"2026-09-04T01:12:19","date_gmt":"2026-09-04T05:12:19","guid":{"rendered":"https:\/\/passcontractorexam.com\/articles\/florida-handyman-requirements\/"},"modified":"2026-11-01T01:00:30","modified_gmt":"2026-11-01T05:00:30","slug":"florida-handyman-requirements","status":"publish","type":"post","link":"https:\/\/passcontractorexam.com\/articles\/florida-handyman-requirements\/","title":{"rendered":"Florida Handyman License Requirements: The $2,500 Rule"},"content":{"rendered":"\n<p class=\"wp-block-paragraph\"><strong>Florida handyman license requirements are short, because the state issues no handyman license at all. Section 489.103(9) of the Florida Statutes exempts casual, minor work where the whole contract, labor and materials together, comes to less than $2,500. Above that figure, on any regulated trade, or on anything needing a permit, the work belongs to a licensed contractor.<\/strong><\/p>\n\n\n\n<div class=\"msq-audio\" data-article=\"florida-handyman-requirements\" data-minutes=\"15\">\n<style>.msq-audio{margin:1.25em 0 1.75em;padding:16px 18px;background:#F3F1EC;border:1px solid #D9D3C7;border-radius:12px}\n.msq-audio-lead{margin:0 0 8px;font-size:.95em}.msq-audio audio{width:100%;margin:0 0 12px;display:block}\n.msq-toc-title{margin:0 0 6px;font-weight:700}.msq-toc ol{margin:0;padding:0;list-style:none}\n.msq-toc li{display:flex;gap:10px;align-items:center;padding:6px 6px;border-bottom:1px solid #D9D3C7;border-radius:8px}\n.msq-toc li:last-child{border-bottom:0}.msq-toc li.is-active{background:#fff}\n.msq-toc-play{flex:0 0 auto;width:30px;height:30px;border-radius:50%;border:0;background:#24405E;color:#fff;font:inherit;font-size:.72em;line-height:30px;padding:0;cursor:pointer}\n.msq-toc-play.is-playing{background:#C4540E}\n.msq-toc-time{flex:0 0 auto;min-width:3.1em;font-variant-numeric:tabular-nums;color:#4C5561;font-size:.9em}\n.msq-toc a{color:#1B1F24;text-decoration:none;line-height:1.35}.msq-toc li.is-active a{font-weight:700;color:#24405E}\n.msq-audio-note{margin:10px 0 0;font-size:.82em;color:#4C5561}\nh2.wp-block-heading[id]{scroll-margin-top:24px}\n.msq-hplay{display:inline-block;vertical-align:middle;width:26px;height:26px;margin:0 0 0 10px;border-radius:50%;border:0;background:#24405E;cursor:pointer;padding:0;position:relative;top:-2px}\n.msq-hplay::before{content:'\u25b6\ufe0e';display:block;color:#fff;font-size:11px;line-height:26px;text-align:center}\n.msq-hplay.is-playing{background:#C4540E}.msq-hplay.is-playing::before{content:'\u2016';font-size:13px;font-weight:700}\n.msq-bar{position:fixed;left:0;right:0;bottom:0;z-index:9000;display:flex;align-items:center;gap:10px;padding:8px 12px;padding-bottom:calc(8px + env(safe-area-inset-bottom));background:#FFFFFF;border-top:1px solid #D9D3C7;box-shadow:0 -4px 16px rgba(0,0,0,.08);font-size:.92em;color:#1B1F24;transition:transform .2s ease}\n.msq-bar.is-hidden{transform:translateY(130%)}\n.msq-bar-play{display:inline-flex;align-items:center;gap:8px;border:0;border-radius:999px;background:#24405E;color:#fff;font:inherit;font-weight:700;padding:8px 14px 8px 12px;cursor:pointer;white-space:nowrap}\n.msq-bar-play.is-playing{background:#C4540E}\n.msq-bar-icon::before{content:'\u25b6\ufe0e';font-size:12px}.msq-bar-play.is-playing .msq-bar-icon::before{content:'\u2016';font-size:14px;font-weight:700}\n.msq-bar-chapter{flex:1 1 auto;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}\n.msq-bar-time{flex:0 0 auto;font-variant-numeric:tabular-nums;color:#4C5561;font-size:.9em}\n.msq-bar-rate,.msq-bar-close{flex:0 0 auto;border:1px solid #D9D3C7;background:#fff;color:#1B1F24;font:inherit;font-size:.85em;line-height:1;border-radius:8px;padding:7px 9px;cursor:pointer}\n.msq-bar-close::before{content:'\u2715'}\n.msq-bar.msq-bar-pill{left:auto;right:14px;bottom:14px;padding:6px;padding-bottom:6px;border:1px solid #D9D3C7;border-radius:999px;box-shadow:0 6px 20px rgba(0,0,0,.15)}\n.msq-bar.msq-bar-pill .msq-bar-chapter,.msq-bar.msq-bar-pill .msq-bar-time,.msq-bar.msq-bar-pill .msq-bar-rate{display:none}\nbody.msq-has-bar{padding-bottom:76px}\n@media (max-width:600px){.msq-bar-time{display:none}.msq-bar{gap:8px;padding-left:10px;padding-right:10px}}\n.msq-s.msq-now{background:#F3F1EC;box-shadow:0 2px 0 #24405E;border-radius:2px}\ntr.msq-now td,tr.msq-now th{background:#F3F1EC;box-shadow:inset 0 -2px 0 #24405E}\n@media (hover:hover){.msq-s,tr[data-i]{cursor:pointer}.msq-s:hover{background:#F3F1EC}}<\/style>\n<script type=\"application\/ld+json\">{\"@context\":\"https:\/\/schema.org\",\"@type\":\"AudioObject\",\"@id\":\"https:\/\/passcontractorexam.com\/articles\/florida-handyman-requirements\/#audio\",\"name\":\"Florida Handyman License Requirements: The $2,500 Rule, read aloud\",\"description\":\"Synthetic voice reading of the article, recorded 24 October 2026.\",\"contentUrl\":\"https:\/\/passcontractorexam.com\/articles\/wp-content\/uploads\/2026\/10\/florida-handyman-requirements-audio-202610241025.mp3\",\"encodingFormat\":\"audio\/mpeg\",\"duration\":\"PT15M12S\",\"uploadDate\":\"2026-10-24\",\"inLanguage\":\"en-US\",\"isAccessibleForFree\":true,\"mainEntityOfPage\":\"https:\/\/passcontractorexam.com\/articles\/florida-handyman-requirements\/\",\"hasPart\":[{\"@type\":\"Clip\",\"name\":\"Florida Handyman License Requirements: The $2,500 Rule\",\"startOffset\":0,\"endOffset\":110},{\"@type\":\"Clip\",\"name\":\"Is there such a thing as a handyman license in Florida?\",\"startOffset\":110,\"endOffset\":161,\"url\":\"https:\/\/passcontractorexam.com\/articles\/florida-handyman-requirements\/#is-there-such-a-thing-as-a-handyman-license-in-florida\"},{\"@type\":\"Clip\",\"name\":\"What does the $2,500 exemption actually cover?\",\"startOffset\":161,\"endOffset\":264,\"url\":\"https:\/\/passcontractorexam.com\/articles\/florida-handyman-requirements\/#what-does-the-2-500-exemption-actually-cover\"},{\"@type\":\"Clip\",\"name\":\"Which jobs fall inside the exemption and which do not?\",\"startOffset\":264,\"endOffset\":364,\"url\":\"https:\/\/passcontractorexam.com\/articles\/florida-handyman-requirements\/#which-jobs-fall-inside-the-exemption-and-which-do-not\"},{\"@type\":\"Clip\",\"name\":\"Does the exemption let you skip the building permit?\",\"startOffset\":364,\"endOffset\":424,\"url\":\"https:\/\/passcontractorexam.com\/articles\/florida-handyman-requirements\/#does-the-exemption-let-you-skip-the-building-permit\"},{\"@type\":\"Clip\",\"name\":\"What about work on your own home?\",\"startOffset\":424,\"endOffset\":504,\"url\":\"https:\/\/passcontractorexam.com\/articles\/florida-handyman-requirements\/#what-about-work-on-your-own-home\"},{\"@type\":\"Clip\",\"name\":\"What happens if you are caught contracting without a license?\",\"startOffset\":504,\"endOffset\":646,\"url\":\"https:\/\/passcontractorexam.com\/articles\/florida-handyman-requirements\/#what-happens-if-you-are-caught-contracting-without-a-license\"},{\"@type\":\"Clip\",\"name\":\"Is a county business tax receipt the same as a license?\",\"startOffset\":646,\"endOffset\":719,\"url\":\"https:\/\/passcontractorexam.com\/articles\/florida-handyman-requirements\/#is-a-county-business-tax-receipt-the-same-as-a-license\"},{\"@type\":\"Clip\",\"name\":\"When is it worth getting licensed instead?\",\"startOffset\":719,\"endOffset\":792,\"url\":\"https:\/\/passcontractorexam.com\/articles\/florida-handyman-requirements\/#when-is-it-worth-getting-licensed-instead\"},{\"@type\":\"Clip\",\"name\":\"What could not be verified for this article?\",\"startOffset\":792,\"endOffset\":912,\"url\":\"https:\/\/passcontractorexam.com\/articles\/florida-handyman-requirements\/#what-could-not-be-verified-for-this-article\"}],\"contentSize\":\"6.4 MB\"}<\/script>\n<p class=\"msq-audio-lead\"><strong>Listen to this article<\/strong>, about 15 minutes. A synthetic voice reads the article and announces each section title as it begins; tables are read row by row and the questions at the end are left out.<\/p>\n<audio class=\"msq-audio-player\" controls preload=\"metadata\" src=\"https:\/\/passcontractorexam.com\/articles\/wp-content\/uploads\/2026\/10\/florida-handyman-requirements-audio-202610241025.mp3\"><\/audio>\n<nav class=\"msq-toc\" aria-label=\"In this article\"><p class=\"msq-toc-title\">In this article<\/p>\n<ol>\n<li data-start=\"0.0\"><button type=\"button\" class=\"msq-toc-play\" data-start=\"0.0\" aria-label=\"Play from: Florida Handyman License Requirements: The $2,500 Rule\">&#x25B6;&#xFE0E;<\/button><span class=\"msq-toc-time\">0:00<\/span><a href=\"#top\">Florida Handyman License Requirements: The $2,500 Rule<\/a><\/li>\n<li data-start=\"110.46\"><button type=\"button\" class=\"msq-toc-play\" data-start=\"110.46\" aria-label=\"Play from: Is there such a thing as a handyman license in Florida?\">&#x25B6;&#xFE0E;<\/button><span class=\"msq-toc-time\">1:50<\/span><a href=\"#is-there-such-a-thing-as-a-handyman-license-in-florida\">Is there such a thing as a handyman license in Florida?<\/a><\/li>\n<li data-start=\"160.76\"><button type=\"button\" class=\"msq-toc-play\" data-start=\"160.76\" aria-label=\"Play from: What does the $2,500 exemption actually cover?\">&#x25B6;&#xFE0E;<\/button><span class=\"msq-toc-time\">2:41<\/span><a href=\"#what-does-the-2-500-exemption-actually-cover\">What does the $2,500 exemption actually cover?<\/a><\/li>\n<li data-start=\"263.86\"><button type=\"button\" class=\"msq-toc-play\" data-start=\"263.86\" aria-label=\"Play from: Which jobs fall inside the exemption and which do not?\">&#x25B6;&#xFE0E;<\/button><span class=\"msq-toc-time\">4:24<\/span><a href=\"#which-jobs-fall-inside-the-exemption-and-which-do-not\">Which jobs fall inside the exemption and which do not?<\/a><\/li>\n<li data-start=\"363.72\"><button type=\"button\" class=\"msq-toc-play\" data-start=\"363.72\" aria-label=\"Play from: Does the exemption let you skip the building permit?\">&#x25B6;&#xFE0E;<\/button><span class=\"msq-toc-time\">6:04<\/span><a href=\"#does-the-exemption-let-you-skip-the-building-permit\">Does the exemption let you skip the building permit?<\/a><\/li>\n<li data-start=\"423.86\"><button type=\"button\" class=\"msq-toc-play\" data-start=\"423.86\" aria-label=\"Play from: What about work on your own home?\">&#x25B6;&#xFE0E;<\/button><span class=\"msq-toc-time\">7:04<\/span><a href=\"#what-about-work-on-your-own-home\">What about work on your own home?<\/a><\/li>\n<li data-start=\"503.96\"><button type=\"button\" class=\"msq-toc-play\" data-start=\"503.96\" aria-label=\"Play from: What happens if you are caught contracting without a license?\">&#x25B6;&#xFE0E;<\/button><span class=\"msq-toc-time\">8:24<\/span><a href=\"#what-happens-if-you-are-caught-contracting-without-a-license\">What happens if you are caught contracting without a license?<\/a><\/li>\n<li data-start=\"645.9\"><button type=\"button\" class=\"msq-toc-play\" data-start=\"645.9\" aria-label=\"Play from: Is a county business tax receipt the same as a license?\">&#x25B6;&#xFE0E;<\/button><span class=\"msq-toc-time\">10:46<\/span><a href=\"#is-a-county-business-tax-receipt-the-same-as-a-license\">Is a county business tax receipt the same as a license?<\/a><\/li>\n<li data-start=\"718.56\"><button type=\"button\" class=\"msq-toc-play\" data-start=\"718.56\" aria-label=\"Play from: When is it worth getting licensed instead?\">&#x25B6;&#xFE0E;<\/button><span class=\"msq-toc-time\">11:59<\/span><a href=\"#when-is-it-worth-getting-licensed-instead\">When is it worth getting licensed instead?<\/a><\/li>\n<li data-start=\"791.62\"><button type=\"button\" class=\"msq-toc-play\" data-start=\"791.62\" aria-label=\"Play from: What could not be verified for this article?\">&#x25B6;&#xFE0E;<\/button><span class=\"msq-toc-time\">13:12<\/span><a href=\"#what-could-not-be-verified-for-this-article\">What could not be verified for this article?<\/a><\/li>\n<\/ol><\/nav>\n<p class=\"msq-audio-note\">Recorded 24 October 2026 from the article as published that day. Press a chapter to jump there; the highlighted line is what is playing. A play button sits beside every section heading, and once you scroll past this player a bar at the bottom of the screen keeps the controls in reach. Tap or click any sentence to hear the reading start from there.<\/p>\n<script>var MSQ_SENT = [[0.0,\"h\",\"floridahandymanlicensere\",45],[4.28,\"p\",\"floridahandymanlicensere\",85],[10.6,\"p\",\"section4891039oftheflori\",121],[24.08,\"p\",\"abovethatfigureonanyregu\",95],[31.92,\"p\",\"onthispagewhythereisnoha\",258],[52.88,\"p\",\"that2500figureisthefirst\",73],[59.04,\"p\",\"pageafterpagestillsays10\",55],[64.36,\"p\",\"thelimitwas1000untilcshb\",121],[79.36,\"p\",\"sixyearsisalongtimeforan\",40],[82.04,\"p\",\"ifyouhavebeensizingjobst\",94],[88.2,\"p\",\"thesecondthingtogetright\",78],[92.88,\"p\",\"a400jobcanstillbeillegal\",72],[98.72,\"p\",\"thatiswherepeoplewhothou\",56],[101.76,\"p\",\"airconditioningisoneofth\",134],[110.46,\"h\",\"istheresuchathingasahand\",44],[113.38,\"p\",\"nothereisnostatehandyman\",115],[121.46,\"p\",\"whensomeoneadvertisesali\",169],[132.38,\"p\",\"whichofthethreeitistakes\",159],[142.5,\"p\",\"thatsoundslikegoodnewsan\",30],[144.34,\"p\",\"thereisnocheapcredential\",55],[147.9,\"p\",\"whatexistsinsteadisalist\",51],[154.7,\"p\",\"fitoneandyoumayworkwitho\",34],[157.02,\"p\",\"fitnoneandnoamountofcare\",44],[160.76,\"h\",\"whatdoesthe2500exemption\",37],[164.48,\"p\",\"thestatuteexemptsinitsow\",164],[178.08,\"p\",\"readthatsentencetwice\",21],[179.56,\"p\",\"everyclauseinitisdoingwo\",26],[181.92,\"p\",\"casualminororinconsequen\",28],[184.4,\"p\",\"thedollarfigureisaceilin\",39],[187.44,\"p\",\"workthatisstructurallysi\",67],[191.44,\"p\",\"aggregatecontractprice\",22],[193.64,\"p\",\"laborplusmaterialsplusev\",36],[196.2,\"p\",\"notyourlaborcharge\",18],[197.36,\"p\",\"notyourprofit\",13],[198.48,\"p\",\"thewholeinvoice\",15],[199.6,\"p\",\"lessthan2500\",12],[202.08,\"p\",\"undernotupto\",12],[203.16,\"p\",\"ajobpricedatexactly2500i\",44],[207.24,\"p\",\"workoroperation\",15],[208.68,\"p\",\"theunittestedisthejobnot\",48],[212.44,\"p\",\"thestatutethenclosestwod\",38],[215.04,\"p\",\"theexemptiondoesnotapply\",194],[231.4,\"p\",\"botharewrittenintothesec\",49],[235.32,\"p\",\"thereisathirdconditionth\",53],[238.48,\"p\",\"theexemptionislostifyouh\",51],[241.08,\"p\",\"advertisingyourselfasaco\",142],[254.8,\"p\",\"theexemptionisadescripti\",39],[257.48,\"p\",\"itisnotastatusyouacquire\",48],[261.36,\"p\",\"itistestedfresheverytime\",24],[263.86,\"h\",\"whichjobsfallinsidetheex\",44],[267.22,\"p\",\"thewordingresolvesquickl\",40],[269.46,\"p\",\"theseexamplesassumenoloc\",113],[276.94,\"t\",\"replacinga180lightfittin\",119],[287.26,\"t\",\"repaintingtwobedroomsfor\",110],[298.7,\"t\",\"rehangingasagginginterio\",94],[309.58,\"t\",\"retilingabathroomflooras\",122],[320.9,\"t\",\"thatsametilinginsidea280\",115],[332.54,\"t\",\"swappingafailedwaterheat\",99],[342.46,\"t\",\"splittingan8000jobintofo\",114],[353.9,\"t\",\"reroofingashedfor1400\",95],[363.72,\"h\",\"doestheexemptionletyousk\",43],[366.48,\"p\",\"itdoesnotandthisisthesin\",63],[370.4,\"p\",\"section489103isaboutlice\",29],[376.44,\"p\",\"itsaysnothingaboutpermit\",25],[378.6,\"p\",\"permitrequirementsareset\",128],[385.72,\"p\",\"inpracticethetwotracksme\",38],[388.96,\"p\",\"abuildingdepartmentwilln\",75],[394.36,\"p\",\"theonlyordinaryroutetoap\",141],[404.84,\"p\",\"ifthejobneedsapermittheh\",52],[408.08,\"p\",\"turnthataroundandyouhave\",35],[410.32,\"p\",\"beforeyouquoteaskthebuil\",64],[414.32,\"p\",\"ifitdoesyouneedalicenseo\",42],[417.76,\"p\",\"ifitdoesnotpriceandtrade\",68],[423.86,\"h\",\"whataboutworkonyourownho\",26],[425.5,\"p\",\"ownerbuilderisadifferent\",116],[435.62,\"p\",\"forafarmoutbuildingoraon\",122],[444.1,\"p\",\"oncommercialpropertythec\",37],[448.1,\"p\",\"theconditionsarewhereitb\",28],[450.02,\"p\",\"yousupervisetheconstruct\",49],[453.66,\"p\",\"yousignthepermitapplicat\",124],[461.42,\"p\",\"andthepropertyhastobefor\",202],[478.42,\"p\",\"thatclauseexiststostoppe\",49],[481.9,\"p\",\"youalsomaynotdelegatethe\",70],[487.98,\"p\",\"itisalsonotaworkaroundfo\",53],[491.66,\"p\",\"theexemptionbelongstothe\",54],[495.54,\"p\",\"handingthejobtoanunlicen\",128],[503.96,\"h\",\"whathappensifyouarecaugh\",51],[507.44,\"p\",\"morethanmostpeopleassume\",80],[512.6,\"t\",\"firstoffencecontractingw\",85],[521.64,\"t\",\"afurtheroffenceafterapre\",85],[532.84,\"t\",\"anyoffenceduringastateof\",110],[543.8,\"t\",\"administrativeactionbyth\",107],[555.84,\"p\",\"chapter489doesnotsetthej\",87],[563.84,\"p\",\"section775082capsafirstd\",117],[580.96,\"p\",\"countiesandcitiescanalso\",128],[593.28,\"p\",\"thestateofemergencyclaus\",47],[596.48,\"p\",\"floridadeclaresemergenci\",116],[604.96,\"p\",\"thejobthatwouldbeamisdem\",53],[608.44,\"p\",\"thereisacivilsidetooandi\",54],[612.0,\"p\",\"section489128makesacontr\",186],[632.28,\"p\",\"thecustomercanstillenfor\",76],[636.92,\"p\",\"sothepracticalriskisnoto\",38],[640.16,\"p\",\"itisdoingtheworknotbeing\",62],[645.9,\"h\",\"isacountybusinesstaxrece\",44],[649.22,\"p\",\"noandthisiswherealotofho\",47],[652.22,\"p\",\"alocalbusinesstaxreceipt\",91],[659.22,\"p\",\"itsaysyoupaidtotradeinth\",31],[660.9,\"p\",\"itsaysnothingaboutwhethe\",69],[664.78,\"p\",\"thelawtreatsthetwoassepa\",44],[667.98,\"p\",\"section205194saysthatfor\",203],[683.78,\"p\",\"andsection489128saysplai\",108],[694.98,\"p\",\"sothereceiptonyourwallis\",84],[701.38,\"p\",\"whatdecidesthelegalquest\",82],[706.98,\"p\",\"somecountiesgofurtherand\",155],[718.56,\"h\",\"whenisitworthgettinglice\",35],[721.0,\"p\",\"thehonestanswerisarithme\",27],[723.0,\"p\",\"ifyouareregularlyturning\",152],[734.12,\"p\",\"thestaterouterunsthrough\",129],[742.88,\"p\",\"wesetallofitoutinthefull\",52],[746.04,\"p\",\"ifyouknowyourcategoryhow\",211],[758.84,\"p\",\"onceyouholdthelicensethe\",110],[767.12,\"p\",\"theexamsthemselvesareles\",62],[771.76,\"p\",\"allthreepartsareopenbook\",93],[778.76,\"p\",\"theexceptionisplumbingwh\",168],[791.62,\"h\",\"whatcouldnotbeverifiedfo\",36],[793.98,\"p\",\"the2500thresholdthecondi\",267],[823.98,\"p\",\"thoseareprimarysourcesan\",43],[826.22,\"p\",\"twogapsfromthefirstversi\",38],[829.54,\"p\",\"on24october2026theflorid\",159],[854.3,\"p\",\"thejailandfinemaximanowc\",62],[864.38,\"p\",\"onethingisstillnotchecke\",102],[871.46,\"p\",\"localrulesarethestanding\",39],[874.38,\"p\",\"countiesandcitiesmaylice\",60],[879.34,\"p\",\"callyourbuildingdepartme\",40],[881.38,\"p\",\"irrigationisthecleareste\",153],[891.26,\"p\",\"itistheonlysourceauthori\",99],[897.98,\"p\",\"palmbeachcountyshowshowf\",174]];\n(function(){\n  function init(){\n  var root = document.querySelector('.msq-audio'); if (!root) { return; }\n  var audio = root.querySelector('audio'), items = Array.prototype.slice.call(root.querySelectorAll('.msq-toc li'));\n  var starts = items.map(function(li){ return parseFloat(li.getAttribute('data-start')) || 0; });\n  var names = items.map(function(li){ return li.querySelector('a').textContent; });\n  var anchors = items.map(function(li){ var h = li.querySelector('a').getAttribute('href') || ''; return (h.charAt(0) === '#' && h !== '#top') ? document.getElementById(h.slice(1)) : null; });\n  var article = root.getAttribute('data-article') || location.pathname, minutes = root.getAttribute('data-minutes') || '';\n  var marks = {}, started = false, pausedAt = -1, closed = false, ended = false;\n  var RATES = [1, 1.25, 1.5], rate = 1;\n  try { var saved = parseFloat(localStorage.getItem('msq-audio-rate')); if (RATES.indexOf(saved) >= 0) { rate = saved; } } catch (e) {}\n  audio.playbackRate = rate;\n  function track(name, extra){ try { if (typeof gtag === 'function') { var p = { article: article }; for (var k in extra) { p[k] = extra[k]; } gtag('event', name, p); } } catch (e) {} }\n  function current(){ var t = audio.currentTime, idx = 0; for (var i = 0; starts.length > i; i += 1) { if (t + 0.25 >= starts[i]) { idx = i; } } return idx; }\n  function onScreen(){\n    var line = window.innerHeight \/ 3, idx = 0;\n    for (var i = 0; anchors.length > i; i += 1) { var el = anchors[i]; if (el && line >= el.getBoundingClientRect().top) { idx = i; } }\n    return idx;\n  }\n  function fmt(s){ s = Math.max(0, Math.round(s || 0)); var m = Math.floor(s \/ 60), r = s % 60; return m + ':' + (10 > r ? '0' : '') + r; }\n  function play(from, source){\n    if (from !== null) { audio.currentTime = from; }\n    var p = audio.play(); if (p && p.catch) { p.catch(function(){}); }\n    track(from === null ? 'audio_resume' : 'audio_chapter', { chapter: names[current()], start: Math.round(audio.currentTime), source: source });\n  }\n  var hbtns = anchors.map(function(el, i){\n    if (!el) { return null; }\n    var b = document.createElement('button'); b.type = 'button'; b.className = 'msq-hplay'; b.setAttribute('aria-label', 'Play this section: ' + names[i]);\n    b.addEventListener('click', function(){\n      if (!audio.paused && current() === i) { audio.pause(); track('audio_pause', { source: 'heading' }); return; }\n      play(starts[i], 'heading');\n    });\n    el.appendChild(b); return b;\n  });\n  var bar = document.createElement('div'); bar.className = 'msq-bar msq-bar-pill is-hidden'; bar.setAttribute('role', 'region'); bar.setAttribute('aria-label', 'Audio player');\n  var playBtn = document.createElement('button'); playBtn.type = 'button'; playBtn.className = 'msq-bar-play';\n  var icon = document.createElement('span'); icon.className = 'msq-bar-icon'; icon.setAttribute('aria-hidden', 'true');\n  var label = document.createElement('span'); label.className = 'msq-bar-label';\n  playBtn.appendChild(icon); playBtn.appendChild(label);\n  var chap = document.createElement('span'); chap.className = 'msq-bar-chapter';\n  var clock = document.createElement('span'); clock.className = 'msq-bar-time';\n  var rateBtn = document.createElement('button'); rateBtn.type = 'button'; rateBtn.className = 'msq-bar-rate'; rateBtn.setAttribute('aria-label', 'Playback speed');\n  var closeBtn = document.createElement('button'); closeBtn.type = 'button'; closeBtn.className = 'msq-bar-close'; closeBtn.setAttribute('aria-label', 'Close the audio bar');\n  bar.appendChild(playBtn); bar.appendChild(chap); bar.appendChild(clock); bar.appendChild(rateBtn); bar.appendChild(closeBtn);\n  document.body.appendChild(bar);\n  function showRate(){ rateBtn.textContent = (rate === 1 ? '1' : String(rate)) + 'x'; }\n  showRate();\n  rateBtn.addEventListener('click', function(){\n    rate = RATES[(RATES.indexOf(rate) + 1) % RATES.length]; audio.playbackRate = rate; showRate();\n    try { localStorage.setItem('msq-audio-rate', String(rate)); } catch (e) {}\n    track('audio_rate', { rate: rate });\n  });\n  closeBtn.addEventListener('click', function(){\n    closed = true; if (!audio.paused) { audio.pause(); } paint(); track('audio_bar_close', {});\n  });\n  function mode(){\n    if (!audio.paused) { return 'pause'; }\n    if (ended) { return 'again'; }\n    if (!started) { return 'listen'; }\n    return (pausedAt === onScreen()) ? 'resume' : 'section';\n  }\n  playBtn.addEventListener('click', function(){\n    var m = mode();\n    if (m === 'pause') { audio.pause(); track('audio_pause', { source: 'bar' }); return; }\n    if (m === 'again') { ended = false; play(0, 'bar'); return; }\n    if (m === 'resume') { play(null, 'bar'); return; }\n    play(starts[onScreen()], 'bar');\n  });\n  function paint(){\n    var idx = current(), playing = !audio.paused, m = mode();\n    items.forEach(function(li, i){\n      var on = (i === idx) && playing, b = li.querySelector('.msq-toc-play'), a = li.querySelector('a');\n      li.classList.toggle('is-active', on); b.classList.toggle('is-playing', on);\n      b.textContent = on ? '\u2016' : '\u25b6\ufe0e';\n      b.setAttribute('aria-label', (on ? 'Pause: ' : 'Play from: ') + a.textContent);\n    });\n    hbtns.forEach(function(b, i){ if (b) { var on = (i === idx) && playing; b.classList.toggle('is-playing', on); b.setAttribute('aria-label', (on ? 'Pause this section: ' : 'Play this section: ') + names[i]); } });\n    playBtn.classList.toggle('is-playing', playing);\n    label.textContent = m === 'pause' ? 'Pause' : m === 'again' ? 'Play again' : m === 'resume' ? 'Resume' : m === 'section' ? 'Play this section' : 'Listen, ' + minutes + ' min';\n    playBtn.setAttribute('aria-label', label.textContent);\n    chap.textContent = started ? names[(playing || m === 'resume') ? idx : onScreen()] : '';\n    clock.textContent = started ? fmt(audio.currentTime) + ' \/ ' + fmt(audio.duration) : '';\n    bar.classList.toggle('msq-bar-pill', !started);\n    var show = !closed && (started || 0 > root.getBoundingClientRect().bottom);\n    bar.classList.toggle('is-hidden', !show);\n    document.body.classList.toggle('msq-has-bar', show);\n  }\n  root.addEventListener('click', function(e){\n    var b = e.target.closest ? e.target.closest('.msq-toc-play') : null; if (!b) { return; }\n    var li = b.parentNode, s = parseFloat(b.getAttribute('data-start')) || 0;\n    if (!audio.paused && current() === items.indexOf(li)) { audio.pause(); track('audio_pause', { source: 'index' }); return; }\n    play(s, 'index');\n  });\n  audio.addEventListener('play', function(){ ended = false; closed = false; if (!started) { started = true; track('audio_play', { minutes: Math.round((audio.duration || 0) \/ 60) }); } paint(); });\n  audio.addEventListener('pause', function(){ pausedAt = current(); paint(); });\n  audio.addEventListener('timeupdate', function(){\n    paint();\n    if (audio.duration > 0) {\n      var pct = Math.floor(audio.currentTime \/ audio.duration * 100);\n      [25, 50, 75].forEach(function(m){ if (pct >= m && !marks[m]) { marks[m] = true; track('audio_progress', { percent: m }); } });\n    }\n  });\n  audio.addEventListener('ended', function(){ ended = true; track('audio_complete', {}); paint(); });\n  var ticking = false;\n  function onScroll(){ if (ticking) { return; } ticking = true; setTimeout(function(){ ticking = false; paint(); }, 80); }\n  window.addEventListener('scroll', onScroll, { passive: true }); window.addEventListener('resize', onScroll);\n  paint();\n  }\n  if (document.readyState === 'loading') { document.addEventListener('DOMContentLoaded', init); } else { init(); }\n})();\n\n(function(){\n  function start(){\n    var root = document.querySelector('.msq-audio'), audio = root ? root.querySelector('audio') : null;\n    var map = (typeof MSQ_SENT !== 'undefined') ? MSQ_SENT : [];\n    if (!root || !audio || !map.length) { return; }\n    var scope = root.closest('main') || root.closest('article') || root.closest('.entry-content') || document.body;\n    var SKIP = '.msq-audio,.msq,.msq-tool,.msq-end,.msq-bar,script,style,noscript,figcaption,#rank-math-faq,.rank-math-block,nav,header,footer';\n    function norm(s){ return s.toLowerCase().replace(\/[^a-z0-9]+\/g, ''); }\n    var nodes = [], stream = '', walker = document.createTreeWalker(scope, NodeFilter.SHOW_TEXT, null), n;\n    while ((n = walker.nextNode())) {\n      var el = n.parentElement; if (!el || el.closest(SKIP)) { continue; }\n      var raw = n.nodeValue, keep = [], norms = '';\n      for (var i = 0; raw.length > i; i += 1) { var c = raw.charAt(i).toLowerCase(); if (\/[a-z0-9]\/.test(c)) { keep.push(i); norms += c; } }\n      if (!norms) { continue; }\n      nodes.push({ node: n, a: stream.length, b: stream.length + norms.length, keep: keep });\n      stream += norms;\n    }\n    var segs = [], cursor = 0, lastRow = null;\n    map.forEach(function(m, idx){\n      var kind = m[1], f = m[2], len = m[3];\n      if (kind === 't') {\n        var rows = scope.querySelectorAll('tr'), after = !lastRow;\n        for (var r = 0; rows.length > r; r += 1) {\n          var tr = rows[r];\n          if (!after) { if (tr === lastRow) { after = true; } continue; }\n          var cell = tr.querySelector('td,th');\n          if (cell && norm(cell.textContent).indexOf(f) === 0) { tr.setAttribute('data-i', idx); lastRow = tr; break; }\n        }\n        return;\n      }\n      var p = stream.indexOf(f, cursor); if (0 > p) { return; }\n      segs.push({ i: idx, a: p, b: Math.min(p + len, stream.length) }); cursor = p + len;\n    });\n    var si = 0;\n    nodes.forEach(function(nd){\n      var frag = document.createDocumentFragment(), raw = nd.node.nodeValue, rawPos = 0, any = false;\n      for (var k = si; segs.length > k; k += 1) {\n        var sg = segs[k]; if (sg.a >= nd.b) { break; } if (nd.a >= sg.b) { continue; }\n        var s = Math.max(sg.a, nd.a), e = Math.min(sg.b, nd.b);\n        var rs = nd.keep[s - nd.a], re2 = nd.keep[e - nd.a - 1] + 1;\n        if (rs > rawPos) { frag.appendChild(document.createTextNode(raw.slice(rawPos, rs))); }\n        var span = document.createElement('span'); span.className = 'msq-s'; span.setAttribute('data-i', sg.i); span.textContent = raw.slice(rs, re2);\n        frag.appendChild(span); rawPos = re2; any = true;\n        if (sg.b > nd.b) { break; }\n      }\n      while (segs.length > si && nd.b >= segs[si].b) { si += 1; }\n      if (!any) { return; }\n      if (raw.length > rawPos) { frag.appendChild(document.createTextNode(raw.slice(rawPos))); }\n      nd.node.parentNode.replaceChild(frag, nd.node);\n    });\n    var starts = map.map(function(m){ return m[0]; }), curIdx = -1, lastUser = 0, timer = null, autoUntil = 0, dragging = false;\n    function idxAt(t){ var lo = 0, hi = starts.length; while (hi > lo + 1) { var mid = (lo + hi) >> 1; if (t + 0.15 >= starts[mid]) { lo = mid; } else { hi = mid; } } return (t + 0.15 >= starts[0]) ? lo : -1; }\n    function setNow(i){\n      if (i === curIdx) { return; }\n      Array.prototype.forEach.call(scope.querySelectorAll('.msq-now'), function(el){ el.classList.remove('msq-now'); });\n      curIdx = i; if (0 > i) { return; }\n      var els = scope.querySelectorAll('[data-i=\"' + i + '\"]'); if (!els.length) { return; }\n      Array.prototype.forEach.call(els, function(el){ el.classList.add('msq-now'); });\n      var r = els[0].getBoundingClientRect(), now = Date.now();\n      if (!dragging && now > lastUser + 2500 && (80 > r.top || r.bottom > window.innerHeight - 140)) {\n        var reduce = window.matchMedia && window.matchMedia('(prefers-reduced-motion: reduce)').matches;\n        autoUntil = now + (reduce ? 400 : 1600);\n        els[0].scrollIntoView({ block: 'center', behavior: reduce ? 'auto' : 'smooth' });\n      }\n    }\n    function tick(){ if (!audio.paused) { setNow(idxAt(audio.currentTime)); } }\n    function userScrolled(){ lastUser = Date.now(); }\n    ['wheel', 'touchmove', 'keydown'].forEach(function(ev){ window.addEventListener(ev, userScrolled, { passive: true }); });\n    window.addEventListener('scroll', function(){ if (Date.now() > autoUntil) { userScrolled(); } }, { passive: true });\n    window.addEventListener('mousedown', function(e){ if (e.clientX >= document.documentElement.clientWidth) { dragging = true; userScrolled(); } }, { passive: true });\n    window.addEventListener('mouseup', function(){ if (dragging) { dragging = false; userScrolled(); } }, { passive: true });\n    audio.addEventListener('play', function(){ if (timer) { clearInterval(timer); } timer = setInterval(tick, 150); tick(); });\n    audio.addEventListener('pause', function(){ if (timer) { clearInterval(timer); timer = null; } });\n    scope.addEventListener('click', function(e){\n      if (e.target.closest('a, button, input, select, textarea, label, summary, .msq, .msq-tool, .msq-end, .msq-audio, .msq-bar')) { return; }\n      var sel = window.getSelection ? String(window.getSelection()) : '';\n      if (sel && sel.trim()) { return; }\n      var el = e.target.closest('[data-i]'); if (!el) { return; }\n      var i = parseInt(el.getAttribute('data-i'), 10); if (isNaN(i)) { return; }\n      if (!audio.paused && i === curIdx) { return; }\n      lastUser = Date.now();\n      audio.currentTime = starts[i];\n      var p = audio.play(); if (p && p.catch) { p.catch(function(){}); }\n      try { if (typeof gtag === 'function') { gtag('event', 'audio_chapter', { article: location.pathname, source: 'sentence', start: Math.round(starts[i]) }); } } catch (err) {}\n    });\n    audio.addEventListener('seeked', tick);\n    audio.addEventListener('ended', function(){ setNow(-1); });\n  }\n  if (document.readyState === 'loading') { document.addEventListener('DOMContentLoaded', start); } else { start(); }\n})();<\/script>\n<\/div>\n\n\n\n<p class=\"msq-hook wp-block-paragraph\">On this page: why there is no handyman license to hold and what the $2,500 exemption actually says, eight real jobs in one table with why each is in or out, why the exemption never touches the permit question, what the owner builder route really commits you to, and how fast a misdemeanor becomes a felony after a hurricane.<\/p>\n\n\n\n<div class=\"msq\" id=\"ms-quiz\" data-slug=\"florida-handyman-requirements\" data-category=\"Florida contractor licensing\" data-list=\"1\">\n<style>.msq,.msq-hook,.msq-box,.msq-end,.msq-tool{--msq-accent:#24405E;--msq-accent-text:#FFFFFF;--msq-line:#D9D3C7;--msq-warn:#C4540E;--msq-muted:#4C5561;--msq-tint:#F3F1EC;--msq-base:#FFFFFF}\n.msq{margin:1.25em 0 1.75em}\n.msq-hook{border-left:3px solid var(--msq-accent);padding:6px 14px;color:var(--msq-muted);font-size:.97em}\n.msq-box{background:var(--msq-tint);border:1px solid var(--msq-line);border-radius:12px;padding:0}\n.msq-box>summary{cursor:pointer;list-style:none;padding:14px 18px;font-weight:700;color:var(--msq-accent)}\n.msq-box>summary::-webkit-details-marker{display:none}\n.msq-box>summary::before{content:\"+\";display:inline-block;width:1.1em;font-weight:800}\n.msq-box[open]>summary::before{content:\"\\00d7\"}\n.msq-body{padding:2px 18px 18px}\n.msq-intro{margin:0 0 12px;font-size:.95em;color:var(--msq-muted)}\n.msq-list{margin:0;padding:0;list-style:none}\n.msq-q{margin:0 0 18px;padding:0}\n.msq-question{font-weight:700;margin:0 0 8px}\n.msq-options{display:flex;flex-direction:column;gap:8px}\n.msq-opt{text-align:left;background:var(--msq-base);border:1px solid var(--msq-line);border-radius:8px;padding:10px 12px;font:inherit;font-size:.95em;color:inherit;cursor:pointer;line-height:1.35}\n.msq-opt:hover{border-color:var(--msq-accent)}\n.msq-opt[disabled]{cursor:default}\n.msq-opt.is-right{border-color:var(--msq-accent);background:var(--msq-line);font-weight:700}\n.msq-opt.is-wrong{border-color:var(--msq-warn);color:var(--msq-warn)}\n.msq-explain{margin:8px 0 0;font-size:.92em;padding:10px 12px;border-left:3px solid var(--msq-accent);background:var(--msq-base);border-radius:0 8px 8px 0}\n.msq-explain[hidden]{display:none}\n.msq-verdict{font-weight:700}\n.msq-result{margin-top:14px;padding:14px 16px;background:var(--msq-base);border:1px solid var(--msq-line);border-radius:10px}\n.msq-result[hidden]{display:none}\n.msq-result h3{margin:0 0 6px;font-size:1.1em}\n.msq-result p{margin:0 0 8px}\n.msq-jump{margin:0 0 8px;padding-left:1.2em}\n.msq-form{margin-top:10px;display:flex;flex-wrap:wrap;gap:8px;align-items:center}\n.msq-form input[type=email]{flex:1 1 220px;padding:10px 12px;border:1px solid var(--msq-muted);border-radius:8px;font:inherit;background:#fff}\n.msq-btn{background:var(--msq-accent);color:var(--msq-accent-text);border:0;border-radius:8px;padding:11px 18px;font:inherit;font-weight:700;cursor:pointer}\n.msq-btn:hover{filter:brightness(.92)}\n.msq-btn[disabled]{opacity:.7;cursor:default}\n.msq-no{font-size:.9em;color:var(--msq-muted);margin-left:4px}\n.msq-privacy{margin:6px 0 0;font-size:.82em;color:var(--msq-muted);flex-basis:100%}\n.msq-hp{position:absolute;left:-5000px;width:1px;height:1px;overflow:hidden}\n.msq-msg{margin:8px 0 0;font-size:.92em}\n.msq-end{margin:1.5em 0;padding:18px;border:1px solid var(--msq-accent);border-radius:12px;text-align:center;background:var(--msq-tint)}\n.msq-end p{margin:0 0 12px}\n.msq-end .msq-body{text-align:left;padding:16px 0 0}\n.msq-end .msq-start-test[hidden]{display:none}\n.msq-tool{margin:1.5em 0;padding:18px 20px;background:var(--msq-tint);border:1px solid var(--msq-line);border-radius:12px}\n.msq-tool h3{margin:0 0 6px;font-size:1.15em}\n.msq-tool p{margin:0 0 10px}\n.msq-tool .msq-note{font-size:.85em;color:var(--msq-muted);margin:10px 0 0}\n.msq-check label{display:flex;gap:10px;align-items:flex-start;padding:9px 0;border-bottom:1px solid var(--msq-line);cursor:pointer;line-height:1.4}\n.msq-check label:last-of-type{border-bottom:0}\n.msq-check input{margin-top:5px;flex:0 0 auto;width:18px;height:18px;accent-color:var(--msq-accent)}\n.msq-check-count{font-weight:700;margin:10px 0 0}\n.msq-verdict-box{margin:12px 0 0;padding:10px 14px;border-radius:8px;background:var(--msq-base);border-left:3px solid var(--msq-warn)}\n.msq-verdict-box[hidden]{display:none}\n.msq-calc{display:grid;grid-template-columns:1fr 1fr;gap:10px 16px}\n.msq-calc label{display:flex;flex-direction:column;gap:4px;font-size:.92em}\n.msq-calc input,.msq-calc select{padding:8px 10px;border:1px solid var(--msq-muted);border-radius:8px;font:inherit;background:#fff}\n.msq-calc-out{grid-column:1 \/ -1;margin-top:6px;padding:12px 14px;background:var(--msq-base);border-radius:8px;border:1px solid var(--msq-line)}\n.msq-calc-out strong{font-size:1.15em}\n.msq-choose label{display:block;padding:9px 12px;margin:0 0 8px;background:var(--msq-base);border:1px solid var(--msq-line);border-radius:8px;cursor:pointer}\n.msq-choose input{margin-right:8px;accent-color:var(--msq-accent)}\n.msq-choice-result{margin-top:10px;padding:12px 14px;background:var(--msq-base);border-left:3px solid var(--msq-accent);border-radius:0 8px 8px 0}\n.msq-choice-result[hidden]{display:none}\n@media (max-width:600px){.msq-calc{grid-template-columns:1fr}}\nh2.wp-block-heading[id]{scroll-margin-top:24px}<\/style>\n<noscript><style>.msq-explain{display:block !important}<\/style><\/noscript>\n<details class=\"msq-box\">\n<summary>Think you already know this? Five questions, one minute.<\/summary>\n<div class=\"msq-body\">\n<p class=\"msq-intro\">Every answer is on this page. Answer from what you know now; the page fills in the rest.<\/p>\n<ol class=\"msq-list\">\n<li class=\"msq-q\" data-q=\"1\" data-answer=\"b\" data-title=\"Is there such a thing as a handyman license in Florida?\" data-section=\"#is-there-such-a-thing-as-a-handyman-license-in-florida\">\n<p class=\"msq-question\">1. What does Florida issue as a handyman license?<\/p>\n<div class=\"msq-options\" role=\"group\" aria-label=\"Question 1 options\"><button type=\"button\" class=\"msq-opt\" data-opt=\"a\">A state handyman certificate<\/button><button type=\"button\" class=\"msq-opt\" data-opt=\"b\">Nothing: there is no state handyman license, exam or category; what exists is a list of exemptions in section 489.103<\/button><button type=\"button\" class=\"msq-opt\" data-opt=\"c\">A county card valid statewide<\/button><\/div>\n<p class=\"msq-explain\" hidden><span class=\"msq-verdict\"><\/span><a href=\"https:\/\/www.flsenate.gov\/Laws\/Statutes\/2026\/489.103\" target=\"_blank\" rel=\"noopener\">Section 489.103 of the Florida Statutes<\/a> is the whole of it. Fit an exemption and you may work without a license. Fit none and no amount of care about pricing helps you. <a class=\"msq-section\" href=\"#is-there-such-a-thing-as-a-handyman-license-in-florida\">Read the section<\/a><\/p>\n<\/li>\n<li class=\"msq-q\" data-q=\"2\" data-answer=\"b\" data-title=\"What does the $2,500 exemption actually cover?\" data-section=\"#what-does-the-2-500-exemption-actually-cover\">\n<p class=\"msq-question\">2. Under section 489.103(9), what has to come to less than $2,500?<\/p>\n<div class=\"msq-options\" role=\"group\" aria-label=\"Question 2 options\"><button type=\"button\" class=\"msq-opt\" data-opt=\"a\">Your labour charge<\/button><button type=\"button\" class=\"msq-opt\" data-opt=\"b\">The aggregate contract price for labour, materials and all other items, and the work must also be casual, minor or inconsequential<\/button><button type=\"button\" class=\"msq-opt\" data-opt=\"c\">Your profit<\/button><\/div>\n<p class=\"msq-explain\" hidden><span class=\"msq-verdict\"><\/span>Under, not up to: a job priced at exactly $2,500 is outside. The statute also closes two doors by name, work that forms part of a larger operation and jobs split into contracts under the line, and holding yourself out as a contractor loses the exemption even on a job that would otherwise fit. <a class=\"msq-section\" href=\"#what-does-the-2-500-exemption-actually-cover\">Read the section<\/a><\/p>\n<\/li>\n<li class=\"msq-q\" data-q=\"3\" data-answer=\"b\" data-title=\"Which jobs fall inside the exemption and which do not?\" data-section=\"#which-jobs-fall-inside-the-exemption-and-which-do-not\">\n<p class=\"msq-question\">3. Replacing a $180 light fitting on an existing circuit: inside the exemption?<\/p>\n<div class=\"msq-options\" role=\"group\" aria-label=\"Question 3 options\"><button type=\"button\" class=\"msq-opt\" data-opt=\"a\">Yes, it is well under $2,500<\/button><button type=\"button\" class=\"msq-opt\" data-opt=\"b\">No: electrical work is separately regulated, and price is not the test<\/button><button type=\"button\" class=\"msq-opt\" data-opt=\"c\">Only on a weekend<\/button><\/div>\n<p class=\"msq-explain\" hidden><span class=\"msq-verdict\"><\/span>The dollar limit is the least important of the three tests. A $400 job can still be illegal depending on the trade and on whether a permit is involved, which is where people who thought they were being careful get caught. <a class=\"msq-section\" href=\"#which-jobs-fall-inside-the-exemption-and-which-do-not\">Read the section<\/a><\/p>\n<\/li>\n<li class=\"msq-q\" data-q=\"4\" data-answer=\"b\" data-title=\"Does the exemption let you skip the building permit?\" data-section=\"#does-the-exemption-let-you-skip-the-building-permit\">\n<p class=\"msq-question\">4. Does the exemption let you skip the building permit?<\/p>\n<div class=\"msq-options\" role=\"group\" aria-label=\"Question 4 options\"><button type=\"button\" class=\"msq-opt\" data-opt=\"a\">Yes, under $2,500<\/button><button type=\"button\" class=\"msq-opt\" data-opt=\"b\">No: section 489.103 is about licensing, permits run on the Florida Building Code track, and a building department will not issue a permit to an unlicensed person for contracted work<\/button><button type=\"button\" class=\"msq-opt\" data-opt=\"c\">Only for interior work<\/button><\/div>\n<p class=\"msq-explain\" hidden><span class=\"msq-verdict\"><\/span>The only ordinary route to a permit without a contractor license is the owner builder exemption, which belongs to the property owner and not to the person working for them. Before you quote, ask the building department whether the work needs a permit. <a class=\"msq-section\" href=\"#does-the-exemption-let-you-skip-the-building-permit\">Read the section<\/a><\/p>\n<\/li>\n<li class=\"msq-q\" data-q=\"5\" data-answer=\"b\" data-title=\"What happens if you are caught contracting without a license?\" data-section=\"#what-happens-if-you-are-caught-contracting-without-a-license\">\n<p class=\"msq-question\">5. Under section 489.127, what is a first offence of contracting without a license?<\/p>\n<div class=\"msq-options\" role=\"group\" aria-label=\"Question 5 options\"><button type=\"button\" class=\"msq-opt\" data-opt=\"a\">A parking ticket<\/button><button type=\"button\" class=\"msq-opt\" data-opt=\"b\">A first degree misdemeanor; a further offence after a previous finding of guilt, or any offence during a declared state of emergency, is a third degree felony<\/button><button type=\"button\" class=\"msq-opt\" data-opt=\"c\">Always a felony<\/button><\/div>\n<p class=\"msq-explain\" hidden><span class=\"msq-verdict\"><\/span><a href=\"https:\/\/www.flsenate.gov\/Laws\/Statutes\/2026\/489.127\" target=\"_blank\" rel=\"noopener\">Section 489.127<\/a> sets the degrees and <a href=\"https:\/\/www.flsenate.gov\/Laws\/Statutes\/2026\/489.13\" target=\"_blank\" rel=\"noopener\">section 489.13<\/a> adds an administrative fine of up to $10,000 plus the department&#8217;s costs; the fine maxima for each degree sit in <a href=\"https:\/\/www.flsenate.gov\/Laws\/Statutes\/2026\/775.083\" target=\"_blank\" rel=\"noopener\">section 775.083<\/a>. Florida declares emergencies for hurricanes, and post storm repair is exactly when enforcement is most active. <a class=\"msq-section\" href=\"#what-happens-if-you-are-caught-contracting-without-a-license\">Read the section<\/a><\/p>\n<\/li>\n<\/ol>\n<div class=\"msq-result\" hidden><\/div>\n<\/div>\n<\/details>\n<script>(function(){\n  if (window.__msqInit) { return; }\n  window.__msqInit = true;\n  var root = document.getElementById('ms-quiz');\n  if (!root) { return; }\n  var meta = { slug: root.getAttribute('data-slug'), category: root.getAttribute('data-category'),\n               list: root.getAttribute('data-list') || '1' };\n  function qs(el, s){ return el.querySelector(s); }\n  function qsa(el, s){ return Array.prototype.slice.call(el.querySelectorAll(s)); }\n  function track(name, params){\n    try { if (typeof gtag === 'function') { var p = params || {}; p.article = meta.slug; gtag('event', name, p); } } catch (e) {}\n  }\n  function jumpList(missed){\n    if (!missed.length) { return ''; }\n    return '<ul class=\"msq-jump\">' + missed.map(function(q){\n      return '<li><a href=\"' + q.getAttribute('data-section') + '\">' + q.getAttribute('data-title') + '<\/a><\/li>';\n    }).join('') + '<\/ul>';\n  }\n  function emailForm(){\n    return '<div class=\"msq-sub\"><p><strong>Get the next one.<\/strong> We publish new articles on ' + meta.category\n      + ' most weeks and recheck this page on Sundays. Email me when a new article goes up or this page changes.<\/p>'\n      + '<form class=\"msq-form\" method=\"post\" action=\"\/mail\/form.php\" novalidate>'\n      + '<input type=\"hidden\" name=\"list\" value=\"' + meta.list + '\">'\n      + '<input type=\"hidden\" name=\"name\" value=\"\">'\n      + '<label class=\"msq-hp\" aria-hidden=\"true\">Leave this empty<input type=\"text\" name=\"website\" tabindex=\"-1\" autocomplete=\"off\"><\/label>'\n      + '<input type=\"email\" name=\"email\" placeholder=\"you@example.com\" required aria-label=\"Email address\" autocomplete=\"email\">'\n      + '<button type=\"submit\" class=\"msq-btn\">Email me the updates<\/button>'\n      + '<a href=\"#\" class=\"msq-no\">No thanks<\/a>'\n      + '<p class=\"msq-privacy\">We store your email and this page\\'s topic, nothing else. Unsubscribe any time.<\/p>'\n      + '<\/form><p class=\"msq-msg\" aria-live=\"polite\"><\/p><\/div>';\n  }\n  \/* The autoresponder always answers 200 with its own page. A \".msg.err\" box means the\n     address was rejected, \"You're subscribed\" means accepted, and a redirect only happens\n     after a successful subscribe. Same reading as the landing pages on the other sites. *\/\n  function sendForm(form){\n    return fetch(form.getAttribute('action'), { method: 'POST', body: new FormData(form), credentials: 'same-origin', redirect: 'manual' })\n      .then(function(res){\n        if (res.type === 'opaqueredirect') { return { status: 'ok' }; }\n        if (res.status === 404) { return { status: 'notlive' }; }\n        if (!res.ok) { throw new Error('HTTP ' + res.status); }\n        return res.text().then(function(t){\n          var doc = new DOMParser().parseFromString(t, 'text\/html');\n          var err = doc.querySelector('.msg.err');\n          if (err) {\n            var m = err.textContent.trim();\n            if (\/something went wrong\/i.test(m)) { throw new Error(m); }\n            return { status: 'rejected', message: m };\n          }\n          if (\/you.re subscribed\/i.test(doc.body.textContent)) { return { status: 'ok' }; }\n          return { status: 'unknown' };\n        });\n      });\n  }\n  function wireForm(sub){\n    var form = qs(sub, '.msq-form'), msg = qs(sub, '.msq-msg');\n    qs(form, '.msq-no').addEventListener('click', function(e){\n      e.preventDefault();\n      sub.innerHTML = '<p class=\"msq-msg\">No problem. The Sunday refresh keeps this page current either way.<\/p>';\n      track('quiz_email', { result: 'declined' });\n    });\n    form.addEventListener('submit', function(e){\n      e.preventDefault();\n      var input = qs(form, 'input[name=email]'), btn = qs(form, '.msq-btn');\n      var email = input.value.trim(); input.value = email;\n      if (!\/^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$\/.test(email)) { msg.textContent = 'That email does not look right.'; return; }\n      btn.disabled = true; btn.textContent = 'Sending';\n      function reset(){ btn.disabled = false; btn.textContent = 'Email me the updates'; }\n      sendForm(form).then(function(r){\n        if (r.status === 'ok' || r.status === 'unknown') {\n          sub.innerHTML = '<p class=\"msq-msg\"><strong>Done.<\/strong> We will email you when the next article on ' + meta.category\n            + ' goes up and when this page changes. If a confirmation email arrives, click it.<\/p>';\n          track('quiz_email', { result: r.status });\n          if (r.status === 'ok') { track('generate_lead', { method: 'quiz' }); }\n        } else if (r.status === 'notlive') {\n          msg.textContent = 'Sign up is not switched on yet for this site. Nothing was stored.'; reset();\n          track('quiz_email', { result: 'notlive' });\n        } else {\n          msg.textContent = r.message || 'Please check the email address and try again.'; reset();\n          track('quiz_email', { result: 'rejected' });\n        }\n      }).catch(function(){\n        msg.textContent = 'Could not reach the sign up service just now. Nothing was stored.'; reset();\n        track('quiz_email', { result: 'error' });\n      });\n    });\n  }\n  function finish(container, mode, score, total, missed){\n    var result = qs(container, '.msq-result');\n    track('quiz_complete', { mode: mode, score: score, total: total });\n    var h;\n    if (mode === 'pre') {\n      h = '<h3>You knew ' + score + ' of ' + total + ' before reading.<\/h3>';\n      h += (score === total) ? '<p>All of them. Read on anyway; the sections below carry the detail behind each answer.<\/p>'\n                             : '<p>The rest is below. Jump straight to what you missed:<\/p>' + jumpList(missed);\n      try { sessionStorage.setItem('msq-pre-' + meta.slug, String(score)); } catch (e) {}\n    } else {\n      var pre = null;\n      try { pre = sessionStorage.getItem('msq-pre-' + meta.slug); } catch (e) {}\n      h = '<h3>You got ' + score + ' of ' + total + '.<\/h3>';\n      if (pre !== null) { h += '<p>Before reading you had ' + pre + ' of ' + total + '.<\/p>'; }\n      if (missed.length) { h += '<p>Worth a second look:<\/p>' + jumpList(missed); }\n      h += emailForm();\n    }\n    result.innerHTML = h; result.hidden = false;\n    if (mode !== 'pre') { wireForm(qs(result, '.msq-sub')); }\n    result.scrollIntoView({ behavior: 'smooth', block: 'nearest' });\n  }\n  function setup(container, mode){\n    var qEls = qsa(container, '.msq-q'), answered = 0, score = 0, missed = [];\n    qEls.forEach(function(q){\n      var answer = q.getAttribute('data-answer'), opts = qsa(q, '.msq-opt'), explain = qs(q, '.msq-explain');\n      q.removeAttribute('data-done'); explain.hidden = true; qs(explain, '.msq-verdict').textContent = '';\n      opts.forEach(function(b){ b.disabled = false; b.classList.remove('is-right', 'is-wrong'); });\n      opts.forEach(function(b){\n        b.addEventListener('click', function(){\n          if (q.getAttribute('data-done')) { return; }\n          q.setAttribute('data-done', '1');\n          var ok = b.getAttribute('data-opt') === answer;\n          opts.forEach(function(o){ o.disabled = true; if (o.getAttribute('data-opt') === answer) { o.classList.add('is-right'); } });\n          if (ok) { score += 1; } else { b.classList.add('is-wrong'); missed.push(q); }\n          qs(explain, '.msq-verdict').textContent = ok ? 'Right. ' : 'Not quite. ';\n          explain.hidden = false;\n          answered += 1;\n          track('quiz_answer', { mode: mode, question: q.getAttribute('data-q'), correct: ok ? 1 : 0 });\n          if (answered === qEls.length) { finish(container, mode, score, qEls.length, missed); }\n        });\n      });\n    });\n  }\n  var box = qs(root, '.msq-box');\n  setup(root, 'pre');\n  if (box) { box.addEventListener('toggle', function(){ if (box.open) { track('quiz_open', { mode: 'pre' }); } }); }\n  \/* The end block sits far below this script, so it does not exist yet while this runs\n     during parsing. A delegated listener finds it at click time. *\/\n  document.addEventListener('click', function(e){\n    var startBtn = (e.target && e.target.closest) ? e.target.closest('.msq-start-test') : null;\n    if (!startBtn) { return; }\n    var end = startBtn.closest('.msq-end');\n    if (!end) { return; }\n    var mount = qs(end, '.msq-mount');\n    var clone = qs(root, '.msq-body').cloneNode(true);\n    var intro = qs(clone, '.msq-intro');\n    if (intro) { intro.textContent = 'The same five questions, now that you have read the page.'; }\n    var res = qs(clone, '.msq-result'); if (res) { res.hidden = true; res.innerHTML = ''; }\n    mount.innerHTML = ''; mount.appendChild(clone);\n    setup(mount, 'test');\n    startBtn.hidden = true;\n    track('quiz_open', { mode: 'test' });\n    mount.scrollIntoView({ behavior: 'smooth', block: 'start' });\n    var first = qs(mount, '.msq-opt'); if (first) { first.focus({ preventScroll: true }); }\n  });\n  \/* Shared tool behaviour: checklists remember their ticks on this device, and a chooser\n     shows the result for the option picked. Calculators carry their own small script. *\/\n  function initTools(){\n    qsa(document, '.msq-check').forEach(function(box){\n      var key = 'msq-check-' + meta.slug + '-' + (box.getAttribute('data-id') || 'x');\n      var boxes = qsa(box, 'input[type=checkbox]'), count = qs(box, '.msq-check-count');\n      var yes = qs(box, '.msq-verdict-yes'), no = qs(box, '.msq-verdict-no');\n      var saved = {};\n      try { saved = JSON.parse(localStorage.getItem(key) || '{}'); } catch (e) {}\n      boxes.forEach(function(cb, i){ if (saved[i]) { cb.checked = true; } });\n      function refresh(){\n        var n = boxes.filter(function(cb){ return cb.checked; }).length, state = {};\n        boxes.forEach(function(cb, i){ if (cb.checked) { state[i] = 1; } });\n        try { localStorage.setItem(key, JSON.stringify(state)); } catch (e) {}\n        if (count) { count.textContent = n + ' of ' + boxes.length + (box.getAttribute('data-verb') || ' done'); }\n        if (yes && no) { yes.hidden = n === 0; no.hidden = n !== 0; }\n      }\n      boxes.forEach(function(cb){ cb.addEventListener('change', function(){ refresh(); track('tool_check', { tool: box.getAttribute('data-id') }); }); });\n      refresh();\n    });\n    qsa(document, '.msq-choose').forEach(function(box){\n      var results = qsa(box, '.msq-choice-result');\n      qsa(box, 'input[type=radio]').forEach(function(r){\n        r.addEventListener('change', function(){\n          results.forEach(function(el){ el.hidden = el.getAttribute('data-for') !== r.value; });\n          track('tool_choose', { tool: box.getAttribute('data-id'), choice: r.value });\n        });\n      });\n    });\n  }\n  \/\/ read progress: how far down the article the reader has scrolled, fired once per quarter\n  (function(){\n    var art = root.closest('article') || root.parentNode, fired = {};\n    function check(){\n      var top = art.getBoundingClientRect().top + window.pageYOffset, h = art.offsetHeight || 1;\n      var seen = (window.pageYOffset + window.innerHeight - top) \/ h * 100;\n      [25, 50, 75, 100].forEach(function(m){ if (seen >= m && !fired[m]) { fired[m] = true; track('read_progress', { percent: m }); } });\n    }\n    window.addEventListener('scroll', check, { passive: true }); window.addEventListener('load', check);\n  })();\n  if (document.readyState === 'loading') { document.addEventListener('DOMContentLoaded', initTools); } else { initTools(); }\n})();<\/script>\n<\/div>\n\n\n\n<p class=\"wp-block-paragraph\">That $2,500 figure is the first thing to get right, because most of the internet has it wrong. Page after page still says $1,000, including pages updated this year. The limit was $1,000 until <a href=\"https:\/\/www.flsenate.gov\/Session\/Bill\/2020\/1193\" target=\"_blank\" rel=\"noopener\">CS\/HB 1193 of 2020<\/a>, whose Senate summary says it raised the handyman exception from $1,000 to $2,500, with effect from July 1, 2020. Six years is a long time for a number to stay wrong. If you have been sizing jobs to stay under a thousand dollars, you have been leaving money on the table for no reason.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The second thing to get right is that the dollar limit is the least important of the three tests. A $400 job can still be illegal, depending on the trade and on whether a permit is involved. That is where people who thought they were being careful get caught. Air conditioning is one of those regulated trades, and even the licensed route splits into <a href=\"https:\/\/passcontractorexam.com\/articles\/florida-air-conditioning-contractor-license\/\">a Class A or Class B air conditioning contractor license<\/a> by system size.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1200\" height=\"627\" src=\"https:\/\/passcontractorexam.com\/articles\/wp-content\/uploads\/2026\/09\/florida-handyman-requirements-2.jpg\" alt=\"Building inspector in a hard hat and safety vest checking a doorway with a clipboard\" class=\"wp-image-120\" srcset=\"https:\/\/passcontractorexam.com\/articles\/wp-content\/uploads\/2026\/09\/florida-handyman-requirements-2.jpg 1200w, https:\/\/passcontractorexam.com\/articles\/wp-content\/uploads\/2026\/09\/florida-handyman-requirements-2-300x157.jpg 300w, https:\/\/passcontractorexam.com\/articles\/wp-content\/uploads\/2026\/09\/florida-handyman-requirements-2-1024x535.jpg 1024w, https:\/\/passcontractorexam.com\/articles\/wp-content\/uploads\/2026\/09\/florida-handyman-requirements-2-768x401.jpg 768w\" sizes=\"auto, (max-width: 1200px) 100vw, 1200px\" \/><figcaption class=\"wp-block-image__caption\">The permit question is separate from the license question, and it usually decides the job.<\/figcaption><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"is-there-such-a-thing-as-a-handyman-license-in-florida\">Is there such a thing as a handyman license in Florida?<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">No. There is no state handyman license to apply for, no handyman exam and no handyman category at the Construction Industry Licensing Board. When someone advertises a licensed handyman service in Florida they hold either a local county or city certificate, or a state license in one of the construction categories, or in some cases nothing at all. Which of the three it is takes a minute to settle on the state search, and our guide to <a href=\"https:\/\/passcontractorexam.com\/articles\/florida-contractor-license-lookup\/\">reading a Florida contractor license lookup record<\/a> explains what the letters and the status words on it mean.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">That sounds like good news and is not. There is no cheap credential that unlocks small contracting work. What exists instead is a list of exemptions in section 489.103. Fit one and you may work without a license. Fit none and no amount of care about pricing helps you.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"what-does-the-2-500-exemption-actually-cover\">What does the $2,500 exemption actually cover?<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">The statute exempts, in its own words, any work or operation of a casual, minor, or inconsequential nature in which the aggregate contract price for labor, materials, and all other items is less than $2,500. Read that sentence twice. Every clause in it is doing work.<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n\n<li><strong>Casual, minor or inconsequential.<\/strong> The dollar figure is a ceiling, not a definition. Work that is structurally significant does not become minor because it is cheap.<\/li>\n\n\n<li><strong>Aggregate contract price.<\/strong> Labor plus materials plus everything else. Not your labor charge. Not your profit. The whole invoice.<\/li>\n\n\n<li><strong>Less than $2,500.<\/strong> Under, not up to. A job priced at exactly $2,500 is outside the exemption.<\/li>\n\n\n<li><strong>Work or operation.<\/strong> The unit tested is the job, not the contract you wrote for it.<\/li>\n\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">The statute then closes two doors explicitly. The exemption does not apply where the work forms part of a larger or major operation, whether that operation is yours or somebody else&#8217;s, and it does not apply where a job has been split into contracts of less than $2,500 to get under the line. Both are written into the section, not read into it by a court.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">There is a third condition that catches more people than either. The exemption is lost if you hold yourself out as a contractor. Advertising yourself as a contractor, on a truck, a business card, a website or a listing, puts you outside 489.103(9) even on a job that would otherwise sit comfortably inside it.<\/p>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p class=\"wp-block-paragraph\">The exemption is a description of a kind of work. It is not a status you acquire and then carry from job to job. It is tested fresh every time.<\/p>\n<\/blockquote>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"which-jobs-fall-inside-the-exemption-and-which-do-not\">Which jobs fall inside the exemption and which do not?<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">The wording resolves quickly against real jobs. These examples assume no local rule adds anything, which is worth checking, and they turn on the trade and the permit as much as on the price.<\/p>\n\n\n\n<figure class=\"wp-block-table is-style-stripes\"><table><thead><tr><th>The job<\/th><th>Inside the exemption?<\/th><th>Why<\/th><\/tr><\/thead><tbody><tr><td>Replacing a $180 light fitting on an existing circuit<\/td><td>No<\/td><td>Electrical work is separately regulated. Price is not the test<\/td><\/tr><tr><td>Repainting two bedrooms for $900<\/td><td>Not needed<\/td><td>Painting is not a state regulated construction category at all<\/td><\/tr><tr><td>Rehanging a sagging interior door for $300<\/td><td>Yes<\/td><td>Casual, minor, no permit, no regulated trade<\/td><\/tr><tr><td>Retiling a bathroom floor as a standalone repair, $2,200<\/td><td>Probably<\/td><td>Under the ceiling and arguably minor, but check the county<\/td><\/tr><tr><td>That same tiling inside a $28,000 bathroom remodel<\/td><td>No<\/td><td>Part of a larger operation, which the statute rules out by name<\/td><\/tr><tr><td>Swapping a failed water heater for $900<\/td><td>No<\/td><td>Plumbing, and it needs a permit in most jurisdictions<\/td><\/tr><tr><td>Splitting an $8,000 job into four $2,000 contracts<\/td><td>No<\/td><td>Division to evade the limit is written into the statute as void<\/td><\/tr><tr><td>Reroofing a shed for $1,400<\/td><td>No<\/td><td>Roofing is a regulated category with its own license and exam<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<div class=\"msq-tool\" id=\"ms-exempt\">\n<h3>Run a job through the statute&#8217;s own tests<\/h3>\n<p>Six questions, each one a clause of section 489.103(9) or the permit rule. Answer for the job in front of you, not for your business in general, because the exemption is tested fresh every time.<\/p>\n<div class=\"msq-calc\">\n<label>Is the whole invoice, labour and materials and everything else, under $2,500?<select id=\"ex-price\"><option value=\"\">Choose<\/option><option value=\"y\">Yes, under $2,500<\/option><option value=\"n\">No, $2,500 or more<\/option><\/select><\/label>\n<label>Is any of the work in a regulated trade: electrical, plumbing, air conditioning, roofing and the like?<select id=\"ex-trade\"><option value=\"\">Choose<\/option><option value=\"n\">No<\/option><option value=\"y\">Yes<\/option><\/select><\/label>\n<label>Does the job need a building permit?<select id=\"ex-permit\"><option value=\"\">Choose<\/option><option value=\"n\">No, checked with the building department<\/option><option value=\"y\">Yes<\/option><option value=\"u\">Not sure<\/option><\/select><\/label>\n<label>Is it part of a larger or major operation, yours or somebody else&#8217;s?<select id=\"ex-larger\"><option value=\"\">Choose<\/option><option value=\"n\">No, a standalone job<\/option><option value=\"y\">Yes<\/option><\/select><\/label>\n<label>Has a bigger job been divided into contracts under $2,500?<select id=\"ex-split\"><option value=\"\">Choose<\/option><option value=\"n\">No<\/option><option value=\"y\">Yes<\/option><\/select><\/label>\n<label>Do you advertise or hold yourself out as a contractor?<select id=\"ex-holdout\"><option value=\"\">Choose<\/option><option value=\"n\">No<\/option><option value=\"y\">Yes<\/option><\/select><\/label>\n<div class=\"msq-calc-out\" id=\"ex-out\"><\/div>\n<\/div>\n<p class=\"msq-note\">General information, not legal advice. Counties and cities may license trades the state does not; the building department for the address is the only authority for it.<\/p>\n<\/div>\n<script>\n(function(){\n  var ids = ['ex-price', 'ex-trade', 'ex-permit', 'ex-larger', 'ex-split', 'ex-holdout'], out = document.getElementById('ex-out');\n  if (!out) { return; }\n  var fails = {\n    'ex-price': { n: 'the whole invoice is not under $2,500, so section 489.103(9) does not reach it' },\n    'ex-trade': { y: 'a regulated trade is not covered by the dollar exemption, whatever the price' },\n    'ex-permit': { y: 'the job needs a permit, and a building department will not issue one to an unlicensed person for contracted work', u: 'the permit question is open, and it decides the job before price does: ask the building department before you quote' },\n    'ex-larger': { y: 'it forms part of a larger or major operation, which the statute rules out by name' },\n    'ex-split': { y: 'division into contracts under $2,500 to evade the licensing requirement is written into the statute as void' },\n    'ex-holdout': { y: 'holding yourself out as a contractor loses the exemption even on a job that would otherwise fit' }\n  };\n  function run(){\n    var reasons = [], blank = 0;\n    ids.forEach(function(id){\n      var v = document.getElementById(id).value;\n      if (!v) { blank++; return; }\n      if (fails[id][v]) { reasons.push(fails[id][v]); }\n    });\n    if (blank > 0) { out.textContent = 'Answer all six questions for this job.'; return; }\n    if (reasons.length > 0) {\n      out.innerHTML = '<strong>Outside the exemption, on the wording of the statute:<\/strong> ' + reasons.join('; ') + '. That leaves a licensed contractor, or walking away.';\n    } else {\n      out.innerHTML = '<strong>Nothing in the six tests rules it out.<\/strong> That is the wording of section 489.103(9), not a licence to proceed: counties and cities may license trades the state does not, so confirm with the building department for the address.';\n    }\n    try { if (typeof gtag === 'function') { gtag('event', 'tool_calc', { tool: 'exempt-check', article: 'florida-handyman-requirements' }); } } catch (e) {}\n  }\n  ids.forEach(function(id){ document.getElementById(id).addEventListener('change', run); });\n})();\n<\/script>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"does-the-exemption-let-you-skip-the-building-permit\">Does the exemption let you skip the building permit?<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">It does not, and this is the single most expensive misreading of the law we see. Section 489.103 is about licensing. It says nothing about permits. Permit requirements are set by the Florida Building Code and administered by your local building department, and they run on a completely separate track.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">In practice the two tracks meet at the counter. A building department will not issue a permit to an unlicensed person for contracted work. The only ordinary route to a permit without a contractor license is the owner builder exemption, which belongs to the property owner and not to the person working for them. If the job needs a permit, the handyman exemption is irrelevant.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1200\" height=\"627\" src=\"https:\/\/passcontractorexam.com\/articles\/wp-content\/uploads\/2026\/09\/florida-handyman-requirements-3.jpg\" alt=\"Kitchen stripped back mid renovation with a worker and tools, work that needs a licensed contractor\" class=\"wp-image-121\" srcset=\"https:\/\/passcontractorexam.com\/articles\/wp-content\/uploads\/2026\/09\/florida-handyman-requirements-3.jpg 1200w, https:\/\/passcontractorexam.com\/articles\/wp-content\/uploads\/2026\/09\/florida-handyman-requirements-3-300x157.jpg 300w, https:\/\/passcontractorexam.com\/articles\/wp-content\/uploads\/2026\/09\/florida-handyman-requirements-3-1024x535.jpg 1024w, https:\/\/passcontractorexam.com\/articles\/wp-content\/uploads\/2026\/09\/florida-handyman-requirements-3-768x401.jpg 768w\" sizes=\"auto, (max-width: 1200px) 100vw, 1200px\" \/><figcaption class=\"wp-block-image__caption\">Work that forms part of a larger remodel falls outside the exemption whatever it is priced at.<\/figcaption><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">Turn that around and you have a usable rule. Before you quote, ask the building department whether the work needs a permit. If it does, you need a license or you need to walk away. If it does not, price and trade and the larger operation test still all have to clear.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"what-about-work-on-your-own-home\">What about work on your own home?<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Owner builder is a different exemption with different conditions, set out at 489.103(7), and it is genuinely generous on residential property. For a farm outbuilding or a one or two family residence there is no dollar cap at all, provided the building is for your own use and not for sale or lease. On commercial property the ceiling is $75,000.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The conditions are where it bites. You supervise the construction yourself, on site, in person. You sign the permit application personally, with a disclosure that makes you the responsible party for code compliance and for anyone hurt on the job. And the property has to be for your own use: under <a href=\"https:\/\/www.flsenate.gov\/Laws\/Statutes\/2026\/489.103\" target=\"_blank\" rel=\"noopener\">section 489.103(7)<\/a>, selling or leasing it, or even offering it for sale or lease, within 1 year after completion creates a presumption that the construction was undertaken for purposes of sale or lease. That clause exists to stop people building quietly to sell. You also may not delegate the duty to supervise the work directly to any other person.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">It is also not a workaround for hiring an unlicensed contractor. The exemption belongs to the owner and covers the owner&#8217;s own work. Handing the job to an unlicensed crew and putting your name on the permit does not make their work legal, and your name is the one on the paperwork afterwards.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"what-happens-if-you-are-caught-contracting-without-a-license\">What happens if you are caught contracting without a license?<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">More than most people assume, and the escalation to a felony is faster than most people assume too.<\/p>\n\n\n\n<figure class=\"wp-block-table is-style-stripes\"><table><thead><tr><th>Situation<\/th><th>Consequence<\/th><th>Source<\/th><\/tr><\/thead><tbody><tr><td>First offence, contracting without a license<\/td><td>First degree misdemeanor<\/td><td>F.S. 489.127<\/td><\/tr><tr><td>A further offence after a previous finding of guilt<\/td><td>Third degree felony<\/td><td>F.S. 489.127<\/td><\/tr><tr><td>Any offence during a state of emergency declared by the Governor<\/td><td>Third degree felony, first time or not<\/td><td>F.S. 489.127<\/td><\/tr><tr><td>Administrative action by the department<\/td><td>Fine of up to $10,000, plus its investigative and legal costs<\/td><td>F.S. 489.13<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">Chapter 489 does not set the jail time or the fines itself; it points to Florida&#8217;s general penalty sections. <a href=\"https:\/\/www.flsenate.gov\/Laws\/Statutes\/2026\/775.082\" target=\"_blank\" rel=\"noopener\">Section 775.082<\/a> caps a first degree misdemeanor at 1 year and a third degree felony at 5 years, and <a href=\"https:\/\/www.flsenate.gov\/Laws\/Statutes\/2026\/775.083\" target=\"_blank\" rel=\"noopener\">section 775.083<\/a> caps the fines at $1,000 and $5,000. Counties and cities can also cite unlicensed work through their own code enforcement under section 489.127(5), with civil penalties up to $2,000 on a citation.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The state of emergency clause deserves its own sentence. Florida declares emergencies for hurricanes, and post storm repair is exactly when unlicensed work spikes and enforcement is most active. The job that would be a misdemeanor in June is a felony in October.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">There is a civil side too, and it is blunter than most people expect. <a href=\"https:\/\/www.flsenate.gov\/Laws\/Statutes\/2026\/489.128\" target=\"_blank\" rel=\"noopener\">Section 489.128<\/a> makes a contract entered into by an unlicensed contractor unenforceable in law or in equity by the unlicensed contractor, and <a href=\"https:\/\/www.flsenate.gov\/Laws\/Statutes\/2026\/713.02\" target=\"_blank\" rel=\"noopener\">section 713.02(7)<\/a> says no lien shall exist in favor of a contractor who is unlicensed. The customer can still enforce the contract against you; you cannot enforce it against them. So the practical risk is not only prosecution. It is doing the work, not being paid, and having no legal way to chase the money.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1600\" height=\"900\" src=\"https:\/\/passcontractorexam.com\/articles\/wp-content\/uploads\/2026\/09\/florida-handyman-requirements-chart.png\" alt=\"Chart of Florida handyman requirements: the $2,500 exemption ceiling against fines of $1,000, $5,000 and a $10,000 administrative cap.\" class=\"wp-image-309\" srcset=\"https:\/\/passcontractorexam.com\/articles\/wp-content\/uploads\/2026\/09\/florida-handyman-requirements-chart.png 1600w, https:\/\/passcontractorexam.com\/articles\/wp-content\/uploads\/2026\/09\/florida-handyman-requirements-chart-300x169.png 300w, https:\/\/passcontractorexam.com\/articles\/wp-content\/uploads\/2026\/09\/florida-handyman-requirements-chart-1024x576.png 1024w, https:\/\/passcontractorexam.com\/articles\/wp-content\/uploads\/2026\/09\/florida-handyman-requirements-chart-768x432.png 768w, https:\/\/passcontractorexam.com\/articles\/wp-content\/uploads\/2026\/09\/florida-handyman-requirements-chart-1536x864.png 1536w\" sizes=\"auto, (max-width: 1600px) 100vw, 1600px\" \/><figcaption class=\"wp-block-image__caption\">Dollar figures from sections 489.103, 489.127, 489.13 and 775.083 of the Florida Statutes. The civil side is not on the chart: an unlicensed contractor is also in a poor position to enforce a contract or a lien.<\/figcaption><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"is-a-county-business-tax-receipt-the-same-as-a-license\">Is a county business tax receipt the same as a license?<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">No, and this is where a lot of honest handymen get confused. A local business tax receipt, the document most counties and cities issue when you register a business, is a tax. It says you paid to trade in that place. It says nothing about whether you are competent or allowed to do construction work.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The law treats the two as separate in both directions. <a href=\"https:\/\/www.flsenate.gov\/Laws\/Statutes\/2026\/205.194\" target=\"_blank\" rel=\"noopener\">Section 205.194<\/a> says that for any profession the department regulates, the applicant must exhibit an active state certificate, registration, or license before the receipt is issued, so a contractor needs the license first and the receipt second. And <a href=\"https:\/\/www.flsenate.gov\/Laws\/Statutes\/2026\/489.128\" target=\"_blank\" rel=\"noopener\">section 489.128<\/a> says plainly that not holding a business tax receipt does not, on its own, make someone an unlicensed contractor.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">So the receipt on your wall is not a handyman license, and the lack of one is not unlicensed contracting. What decides the legal question is still the job itself, tested against the three conditions above. Some counties go further and certify trades the state leaves alone, which is a separate local license, not the tax receipt; the county guides further down this page show what that looks like.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"when-is-it-worth-getting-licensed-instead\">When is it worth getting licensed instead?<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">The honest answer is arithmetic. If you are regularly turning work down, quietly splitting jobs, or taking permitted work and hoping, the exemption has stopped being a business model and become a risk you carry for free.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The state route runs through experience, financial responsibility, insurance and the examinations, and the paperwork takes longer than the studying does. The financial responsibility step is the one that catches people out: the board wants a FICO derived score of 660, and <a href=\"https:\/\/passcontractorexam.com\/articles\/florida-contractor-license-credit-score\/\">what the Florida contractor license credit score rule asks for<\/a> explains the 14 hour course that stands in for it when the number falls short. We set all of it out in <a href=\"https:\/\/passcontractorexam.com\/articles\/florida-contractor-license-requirements\/\">the full license requirements checklist<\/a>. If you know your category, <a href=\"https:\/\/passcontractorexam.com\/articles\/florida-general-contractor-license\/\">how to get a general contractor license<\/a> covers the broadest one, <a href=\"https:\/\/passcontractorexam.com\/articles\/florida-electrical-contractor-license\/\">the electrical contractor license<\/a> the trade with the strictest separate route, and <a href=\"https:\/\/passcontractorexam.com\/articles\/florida-roofing-license\/\">the roofing license and its scope<\/a> the category most affected by Florida weather. Once you hold the license the upkeep is modest by comparison, at <a href=\"https:\/\/passcontractorexam.com\/articles\/florida-contractor-continuing-education\/\">14 hours of continuing education every two years<\/a> plus the renewal fee.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The exams themselves are less mysterious than the prep industry suggests. All three parts are open book, and <a href=\"https:\/\/passcontractorexam.com\/articles\/florida-contractor-exam-format\/\">how the three exams are structured<\/a> explains what each one is and how long you get. The exception is plumbing, whose trade paper is pencil and paper on fixed dates and carries five hand drawn isometric drawings worth 50 of its 160 points, set out in <a href=\"https:\/\/passcontractorexam.com\/articles\/florida-plumbing-license-exam\/\">our Florida plumbing license exam guide<\/a>.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"what-could-not-be-verified-for-this-article\">What could not be verified for this article?<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">The $2,500 threshold, the conditions that void the exemption, the owner builder terms and the penalty provisions were read directly from the Florida Senate&#8217;s published statute pages for the 2026 edition of sections 489.103, 489.127 and 489.13, reread on 24 October 2026 along with sections 489.128, 713.02, 205.194, 775.082 and 775.083. Those are primary sources and those parts are solid.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Two gaps from the first version are now closed. On 24 October 2026 the Florida Senate&#8217;s summary of <a href=\"https:\/\/www.flsenate.gov\/Session\/Bill\/2020\/1193\" target=\"_blank\" rel=\"noopener\">CS\/HB 1193<\/a> confirmed the move from $1,000 to $2,500 and its July 1, 2020 start, and the history note on section 489.103 lists that law as chapter 2020-160. The jail and fine maxima now come from sections 775.082 and 775.083 directly. One thing is still not checked: the department&#8217;s own guidance pages refuse automated readers, so nothing here relies on them.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Local rules are the standing caveat on all of it. Counties and cities may license trades the state does not, and several do. Call your building department before you quote. Irrigation is the clearest example of a trade licensed at both levels, and <a href=\"https:\/\/passcontractorexam.com\/articles\/irrigation-certification-florida\/\">whether you need the state irrigation certificate or a county card<\/a> turns on how many jurisdictions you work in. It is the only source authoritative for your address, and this article is general information rather than legal advice. Palm Beach County shows how far that can go: it still certifies 23 specialty trades, drywall and fence among them, and our guide to the <a href=\"https:\/\/passcontractorexam.com\/articles\/palm-beach-contractors-license\/\">Palm Beach county certificate, its fees and its 2026 board dates<\/a> lists every one.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"frequently-asked-questions\">Frequently asked questions<\/h2>\n\n\n<div id=\"rank-math-faq\" class=\"rank-math-block\">\n<div class=\"rank-math-list \">\n<div id=\"faq-q-1\" class=\"rank-math-list-item\">\n<h3 class=\"rank-math-question \">Do you need a license to be a handyman in Florida?<\/h3>\n<div class=\"rank-math-answer \">\n\n<p>Not for work that fits an exemption in section 489.103. There is no handyman license to hold in Florida, so the question is never whether you are licensed as a handyman. It is whether each individual job is casual and minor, under $2,500 in total, outside the regulated trades and free of any permit requirement.<\/p>\n\n<\/div>\n<\/div>\n<div id=\"faq-q-2\" class=\"rank-math-list-item\">\n<h3 class=\"rank-math-question \">Is the Florida handyman limit $1,000 or $2,500?<\/h3>\n<div class=\"rank-math-answer \">\n\n<p>The 2026 edition of section 489.103(9) reads $2,500, and so does the 2025 edition. The $1,000 figure was correct years ago and is still repeated across a great many websites. The threshold covers the aggregate contract price for labor, materials and everything else, and the job must be under it rather than at it.<\/p>\n\n<\/div>\n<\/div>\n<div id=\"faq-q-3\" class=\"rank-math-list-item\">\n<h3 class=\"rank-math-question \">Can I split a large job into smaller contracts to stay under the limit?<\/h3>\n<div class=\"rank-math-answer \">\n\n<p>No, and the statute rules it out by name. The exemption does not apply where a division of the operation has been made into contracts of less than $2,500 for the purpose of evading the licensing requirement. It also does not apply where the work forms part of a larger operation, even one that somebody else is carrying out.<\/p>\n\n<\/div>\n<\/div>\n<div id=\"faq-q-4\" class=\"rank-math-list-item\">\n<h3 class=\"rank-math-question \">Does the exemption cover electrical or plumbing work?<\/h3>\n<div class=\"rank-math-answer \">\n\n<p>No. Those trades are regulated separately and the dollar figure does not reach them. A small electrical or plumbing job is still electrical or plumbing work, and it usually needs a permit as well, which closes the second door. Roofing, air conditioning, pools and several other categories sit in the same position.<\/p>\n\n<\/div>\n<\/div>\n<div id=\"faq-q-5\" class=\"rank-math-list-item\">\n<h3 class=\"rank-math-question \">What is the penalty for unlicensed contracting in Florida?<\/h3>\n<div class=\"rank-math-answer \">\n\n<p>Under F.S. 489.127 a first offence is a first degree misdemeanor, and a further offence after a previous finding of guilt is a third degree felony. Any offence committed during a state of emergency declared by the Governor is a third degree felony regardless of history. The department may separately impose an administrative fine of up to $10,000 under F.S. 489.13.<\/p>\n\n<\/div>\n<\/div>\n<div id=\"faq-q-6\" class=\"rank-math-list-item\">\n<h3 class=\"rank-math-question \">Can I do the work on my own house without a license?<\/h3>\n<div class=\"rank-math-answer \">\n\n<p>Usually yes, under the owner builder exemption at 489.103(7). On a one or two family residence there is no dollar cap, provided the property is for your own use and not for sale or lease, and the equivalent commercial ceiling is $75,000. You must supervise the work personally and sign the permit yourself with the statutory disclosure. Selling or leasing the property within 1 year of completion creates a presumption that you built it for sale or lease.<\/p>\n\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n\n\n<div class=\"msq-end\" id=\"ms-quiz-end\">\n<p><strong>Finished the page?<\/strong> The same five questions from the top, to see what stuck.<\/p>\n<button type=\"button\" class=\"msq-btn msq-start-test\">Test Your Understanding of This Article<\/button>\n<div class=\"msq-mount\"><\/div>\n<\/div>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<p class=\"wp-block-paragraph\"><em>Rules and fees change without notice. This page was reread on 24 October 2026 against sections 489.103, 489.127, 489.128, 489.13, 713.02, 205.194, 775.082 and 775.083 of the 2026 Florida Statutes and the Senate summary of CS\/HB 1193. Changed that day: the title, the answer paragraph, the owner builder sale or lease rule (it is a presumption, not a year of occupancy), the penalty sources, the civil side and a new section on business tax receipts. If you hit something different, tell us in the comments.<\/em><\/p>\n","protected":false},"excerpt":{"rendered":"<p>No handyman license exists in Florida. What the $2,500 exemption in section 489.103 actually covers, what voids it, and where the permit rule cuts across it.<\/p>\n","protected":false},"author":1,"featured_media":119,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":"","rank_math_title":"Florida Handyman License Requirements: The $2,500 Rule","rank_math_description":"Florida handyman license requirements: no state handyman license exists, and 489.103(9) exempts only casual jobs under $2,500 that need no permit.","rank_math_focus_keyword":"florida handyman license requirements","rank_math_canonical_url":"","rank_math_breadcrumb_title":"","rank_math_facebook_title":"","rank_math_facebook_description":"","rank_math_facebook_image":"","rank_math_twitter_title":"","rank_math_twitter_description":"","rank_math_twitter_image":"","rank_math_pillar_content":"","rank_math_robots":[],"rank_math_advanced_robots":[]},"categories":[4],"tags":[],"class_list":["post-122","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-licensing"],"_links":{"self":[{"href":"https:\/\/passcontractorexam.com\/articles\/wp-json\/wp\/v2\/posts\/122","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/passcontractorexam.com\/articles\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/passcontractorexam.com\/articles\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/passcontractorexam.com\/articles\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/passcontractorexam.com\/articles\/wp-json\/wp\/v2\/comments?post=122"}],"version-history":[{"count":14,"href":"https:\/\/passcontractorexam.com\/articles\/wp-json\/wp\/v2\/posts\/122\/revisions"}],"predecessor-version":[{"id":802,"href":"https:\/\/passcontractorexam.com\/articles\/wp-json\/wp\/v2\/posts\/122\/revisions\/802"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/passcontractorexam.com\/articles\/wp-json\/wp\/v2\/media\/119"}],"wp:attachment":[{"href":"https:\/\/passcontractorexam.com\/articles\/wp-json\/wp\/v2\/media?parent=122"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/passcontractorexam.com\/articles\/wp-json\/wp\/v2\/categories?post=122"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/passcontractorexam.com\/articles\/wp-json\/wp\/v2\/tags?post=122"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}