[{"data":1,"prerenderedAt":808},["ShallowReactive",2],{"navigation_docs":3,"-api-bulk-csv":54,"-api-bulk-csv-surround":803},[4,18,40],{"title":5,"path":6,"stem":7,"children":8},"Getting Started","\u002Fgetting-started","1.getting-started\u002F1.index",[9,10,14],{"title":5,"path":6,"stem":7},{"title":11,"path":12,"stem":13},"Console Tour","\u002Fgetting-started\u002Fconsole-tour","1.getting-started\u002F2.console-tour",{"title":15,"path":16,"stem":17},"The Free Audit","\u002Fgetting-started\u002Ffree-audit","1.getting-started\u002F3.free-audit",{"title":19,"path":20,"stem":21,"children":22},"MCP Server","\u002Fmcp","2.mcp\u002F1.index",[23,24,28,32,36],{"title":19,"path":20,"stem":21},{"title":25,"path":26,"stem":27},"Setup","\u002Fmcp\u002Fsetup","2.mcp\u002F2.setup",{"title":29,"path":30,"stem":31},"Available Tools","\u002Fmcp\u002Favailable-tools","2.mcp\u002F3.available-tools",{"title":33,"path":34,"stem":35},"Authentication","\u002Fmcp\u002Fauthentication","2.mcp\u002F4.authentication",{"title":37,"path":38,"stem":39},"Troubleshooting","\u002Fmcp\u002Ftroubleshooting","2.mcp\u002F5.troubleshooting",{"title":41,"path":42,"stem":43,"children":44},"API Reference","\u002Fapi","3.api\u002F1.index",[45,46,50],{"title":41,"path":42,"stem":43},{"title":47,"path":48,"stem":49},"Bulk CSV","\u002Fapi\u002Fbulk-csv","3.api\u002F2.bulk-csv",{"title":51,"path":52,"stem":53},"Outbound Webhooks","\u002Fapi\u002Foutbound-webhooks","3.api\u002F3.outbound-webhooks",{"id":55,"title":47,"body":56,"description":796,"extension":797,"links":798,"meta":799,"navigation":800,"path":48,"seo":801,"stem":49,"__hash__":802},"docs\u002F3.api\u002F2.bulk-csv.md",{"type":57,"value":58,"toc":784},"minimark",[59,77,82,124,127,131,134,493,500,504,507,534,537,541,544,662,673,677,723,727,730,744,747,751,754,776],[60,61,62,63,67,68,71,72,76],"p",{},"The ",[64,65,66],"strong",{},"bulk CSV diff-and-apply"," workflow is PlaceOptimizer's flagship way to\nedit many locations at once. You export every location to a CSV, edit it in a\nspreadsheet, import it back, review a field-level diff, and apply only the\nchanges you select. It lives at ",[64,69,70],{},"Locations → Bulk edit","\n(",[73,74,75],"code",{},"\u002Flocations\u002Fbulk",") in the operator console.",[78,79,81],"h2",{"id":80},"the-workflow","The workflow",[83,84,85,92,102,112,118],"ol",{},[86,87,88,91],"li",{},[64,89,90],{},"Export."," Download every managed location as a CSV — one row per\nlocation, a fixed 16-column header.",[86,93,94,97,98,101],{},[64,95,96],{},"Edit."," Open the CSV in a spreadsheet, change the values you want to\ncorrect. Each column maps to one field on the location; leave a cell empty\nto clear that field (or mark a day ",[73,99,100],{},"closed",").",[86,103,104,107,108,111],{},[64,105,106],{},"Import and preview."," Upload the edited CSV. The engine parses it,\nvalidates every row, and computes a ",[64,109,110],{},"field-level diff"," between the\ncurrent locations and your proposed values — it never applies anything\nautomatically.",[86,113,114,117],{},[64,115,116],{},"Review."," The preview shows, per location, exactly which fields would\nchange (before → after), plus any rows that could not be matched and any\nrows with validation errors.",[86,119,120,123],{},[64,121,122],{},"Apply."," Select the locations whose changes you want (or all of them) and\napply. Each location is applied independently — one failing location never\naborts the rest of the batch.",[60,125,126],{},"The diff engine is pure and runs before anything touches your listings. The\npreview is honest: it reports matched, changed, unchanged, unknown, and\nerroring rows in one summary.",[78,128,130],{"id":129},"the-16-column-format","The 16-column format",[60,132,133],{},"The header row is fixed and human-readable for spreadsheet editing. Columns\nappear in this exact order:",[135,136,137,159],"table",{},[138,139,140],"thead",{},[141,142,143,147,150,153,156],"tr",{},[144,145,146],"th",{},"#",[144,148,149],{},"Column",[144,151,152],{},"Field",[144,154,155],{},"Required",[144,157,158],{},"Notes",[160,161,162,186,208,229,252,272,292,312,332,352,378,398,417,436,455,474],"tbody",{},[141,163,164,168,173,178,183],{},[165,166,167],"td",{},"1",[165,169,170],{},[73,171,172],{},"Store Code",[165,174,175],{},[73,176,177],{},"storeCode",[165,179,180],{},[64,181,182],{},"Yes",[165,184,185],{},"The join key that matches a row to an existing location (case-insensitive). Cannot be empty.",[141,187,188,191,196,201,205],{},[165,189,190],{},"2",[165,192,193],{},[73,194,195],{},"Title",[165,197,198],{},[73,199,200],{},"title",[165,202,203],{},[64,204,182],{},[165,206,207],{},"The location name. Cannot be empty.",[141,209,210,213,218,223,226],{},[165,211,212],{},"3",[165,214,215],{},[73,216,217],{},"Phone",[165,219,220],{},[73,221,222],{},"phonePrimary",[165,224,225],{},"No",[165,227,228],{},"Primary phone number.",[141,230,231,234,239,244,246],{},[165,232,233],{},"4",[165,235,236],{},[73,237,238],{},"Address Line",[165,240,241],{},[73,242,243],{},"addressLine",[165,245,225],{},[165,247,248,249,101],{},"Full street address (lines joined with ",[73,250,251],{},", ",[141,253,254,257,262,267,269],{},[165,255,256],{},"5",[165,258,259],{},[73,260,261],{},"Locality",[165,263,264],{},[73,265,266],{},"locality",[165,268,225],{},[165,270,271],{},"City or locality.",[141,273,274,277,282,287,289],{},[165,275,276],{},"6",[165,278,279],{},[73,280,281],{},"Admin Area",[165,283,284],{},[73,285,286],{},"adminArea",[165,288,225],{},[165,290,291],{},"State or admin area.",[141,293,294,297,302,307,309],{},[165,295,296],{},"7",[165,298,299],{},[73,300,301],{},"Postal Code",[165,303,304],{},[73,305,306],{},"postalCode",[165,308,225],{},[165,310,311],{},"PIN \u002F postal code.",[141,313,314,317,322,327,329],{},[165,315,316],{},"8",[165,318,319],{},[73,320,321],{},"Website",[165,323,324],{},[73,325,326],{},"website",[165,328,225],{},[165,330,331],{},"Website URI.",[141,333,334,337,342,347,349],{},[165,335,336],{},"9",[165,338,339],{},[73,340,341],{},"Primary Category",[165,343,344],{},[73,345,346],{},"primaryCategory",[165,348,225],{},[165,350,351],{},"The location's primary GBP category.",[141,353,354,357,362,367,369],{},[165,355,356],{},"10",[165,358,359],{},[73,360,361],{},"Monday",[165,363,364],{},[73,365,366],{},"monday",[165,368,225],{},[165,370,371,372,251,375,377],{},"Weekly hours: ",[73,373,374],{},"HH:MM-HH:MM",[73,376,100],{},", or empty (see below).",[141,379,380,383,388,393,395],{},[165,381,382],{},"11",[165,384,385],{},[73,386,387],{},"Tuesday",[165,389,390],{},[73,391,392],{},"tuesday",[165,394,225],{},[165,396,397],{},"Same format as Monday.",[141,399,400,403,408,413,415],{},[165,401,402],{},"12",[165,404,405],{},[73,406,407],{},"Wednesday",[165,409,410],{},[73,411,412],{},"wednesday",[165,414,225],{},[165,416,397],{},[141,418,419,422,427,432,434],{},[165,420,421],{},"13",[165,423,424],{},[73,425,426],{},"Thursday",[165,428,429],{},[73,430,431],{},"thursday",[165,433,225],{},[165,435,397],{},[141,437,438,441,446,451,453],{},[165,439,440],{},"14",[165,442,443],{},[73,444,445],{},"Friday",[165,447,448],{},[73,449,450],{},"friday",[165,452,225],{},[165,454,397],{},[141,456,457,460,465,470,472],{},[165,458,459],{},"15",[165,461,462],{},[73,463,464],{},"Saturday",[165,466,467],{},[73,468,469],{},"saturday",[165,471,225],{},[165,473,397],{},[141,475,476,479,484,489,491],{},[165,477,478],{},"16",[165,480,481],{},[73,482,483],{},"Sunday",[165,485,486],{},[73,487,488],{},"sunday",[165,490,225],{},[165,492,397],{},[60,494,495,496,499],{},"That is 9 profile columns + 7 day columns = ",[64,497,498],{},"16 columns",".",[78,501,503],{"id":502},"weekly-hours-format","Weekly hours format",[60,505,506],{},"Each day column accepts one of:",[508,509,510,519,524],"ul",{},[86,511,512,514,515,518],{},[73,513,374],{}," — e.g. ",[73,516,517],{},"09:00-21:00"," (a single open period; hours 0–24).",[86,520,521,523],{},[73,522,100],{}," — any case; the location is closed that day.",[86,525,526,530,531,533],{},[527,528,529],"em",{},"(empty)"," — treated as ",[73,532,100],{}," for a day with no trading hours.",[60,535,536],{},"The value is parsed with the same hours helpers the wire mapper uses, so what\nvalidates in the CSV is exactly what is applied.",[78,538,540],{"id":539},"column-data-model-mapping","Column → data model mapping",[60,542,543],{},"The diff engine maps each CSV column to a dotted path on the managed\nlocation model:",[135,545,546,556],{},[138,547,548],{},[141,549,550,553],{},[144,551,552],{},"CSV column",[144,554,555],{},"Data path",[160,557,558,568,579,590,601,612,623,634,645],{},[141,559,560,564],{},[165,561,562],{},[73,563,195],{},[165,565,566],{},[73,567,200],{},[141,569,570,574],{},[165,571,572],{},[73,573,217],{},[165,575,576],{},[73,577,578],{},"phones.primary",[141,580,581,585],{},[165,582,583],{},[73,584,238],{},[165,586,587],{},[73,588,589],{},"address.lines",[141,591,592,596],{},[165,593,594],{},[73,595,261],{},[165,597,598],{},[73,599,600],{},"address.locality",[141,602,603,607],{},[165,604,605],{},[73,606,281],{},[165,608,609],{},[73,610,611],{},"address.adminArea",[141,613,614,618],{},[165,615,616],{},[73,617,301],{},[165,619,620],{},[73,621,622],{},"address.postalCode",[141,624,625,629],{},[165,626,627],{},[73,628,321],{},[165,630,631],{},[73,632,633],{},"websiteUri",[141,635,636,640],{},[165,637,638],{},[73,639,341],{},[165,641,642],{},[73,643,644],{},"categories.primary",[141,646,647,654],{},[165,648,649,651,652],{},[73,650,361],{},"…",[73,653,483],{},[165,655,656,651,659],{},[73,657,658],{},"regularHours.monday",[73,660,661],{},"regularHours.sunday",[60,663,664,665,668,669,672],{},"The preview reports changes as these dotted paths with ",[73,666,667],{},"before"," and ",[73,670,671],{},"after","\nvalues, so what you approve is unambiguous.",[78,674,676],{"id":675},"matching-and-validation-rules","Matching and validation rules",[508,678,679,689,699,705,717],{},[86,680,681,684,685,688],{},[64,682,683],{},"Store Code is the join key."," A row matches a location when its Store Code\nmatches an existing location's store code (trimmed, case-insensitive). Rows\nwhose Store Code matches nothing are reported as ",[64,686,687],{},"unknown"," and are never\nsilently skipped.",[86,690,691,698],{},[64,692,693,668,695,697],{},[73,694,172],{},[73,696,195],{}," are required"," — a row missing either is a\nvalidation error.",[86,700,701,704],{},[64,702,703],{},"Column count is enforced."," A row with the wrong number of columns is\nreported with its row number.",[86,706,707,710,711,713,714,716],{},[64,708,709],{},"Hours are validated per cell."," Anything that is not ",[73,712,374],{}," or\n",[73,715,100],{}," is an error on that row.",[86,718,719,722],{},[64,720,721],{},"Parsing is RFC 4180."," The exporter writes CRLF rows and quotes fields\ncontaining commas, quotes, or newlines; the importer tolerates BOM, CRLF or\nLF, quoted fields with embedded commas\u002Fnewlines, and doubled quotes (Excel\noutput shapes).",[78,724,726],{"id":725},"errors-and-unknown-rows","Errors and unknown rows",[60,728,729],{},"The preview never fails silently. It reports, per row number:",[508,731,732,738],{},[86,733,734,737],{},[64,735,736],{},"Validation errors"," — a required field missing, a malformed hours cell, or\na wrong column count.",[86,739,740,743],{},[64,741,742],{},"Unknown rows"," — valid rows whose Store Code does not match any existing\nlocation.",[60,745,746],{},"You see all of them before applying anything, and you can choose which matched\nlocations to apply changes to.",[78,748,750],{"id":749},"behind-the-scenes-the-preview-and-apply-endpoints","Behind the scenes: the preview and apply endpoints",[60,752,753],{},"The console calls two REST endpoints (console-internal, session-guarded):",[508,755,756,766],{},[86,757,758,761,762,765],{},[73,759,760],{},"POST \u002Fapi\u002Fv1\u002Fgbp\u002Flocations\u002Fimport\u002Fpreview"," with ",[73,763,764],{},"{ \"csv\": \"\u003Ccsv text>\" }","\nreturns the parsed preview: per-location diffs, unknown rows, issues, and a\nsummary of rows, matched, changed, unchanged, unknown, and errors.",[86,767,768,771,772,775],{},[73,769,770],{},"POST \u002Fapi\u002Fv1\u002Fgbp\u002Flocations\u002Fimport\u002Fapply"," with\n",[73,773,774],{},"{ \"changes\": [{ \"locationRef\": \"...\", \"changes\": [...] }] }"," applies the\nconfirmed change sets (up to 1000), isolating per-location failures.",[60,777,778,779,783],{},"These endpoints back the console UI and are not part of the public supported\nAPI surface — use the bulk workflow through the console, or the\n",[780,781,782],"a",{"href":30},"authenticated MCP tools"," for programmatic access.",{"title":785,"searchDepth":786,"depth":786,"links":787},"",3,[788,790,791,792,793,794,795],{"id":80,"depth":789,"text":81},2,{"id":129,"depth":789,"text":130},{"id":502,"depth":789,"text":503},{"id":539,"depth":789,"text":540},{"id":675,"depth":789,"text":676},{"id":725,"depth":789,"text":726},{"id":749,"depth":789,"text":750},"The 16-column bulk CSV format for PlaceOptimizer location edits — column reference, validation rules, and the diff-and-apply flow.","md",null,{},true,{"title":47,"description":796},"CLPuglml0ZjsAameQAlFWHJjvTcQNM3phHK_F3xC9YE",[804,806],{"title":41,"path":42,"stem":43,"description":805,"children":-1},"The PlaceOptimizer programmatic surface — the MCP server is primary; REST endpoints are console-internal, and the bulk CSV format for location edits.",{"title":51,"path":52,"stem":53,"description":807,"children":-1},"Receive PlaceOptimizer events in your own services — endpoint registration, event types, payload shape, HMAC signature verification, retry behavior, and the test endpoint.",1786649635795]