GetFacades agent-API
Fasadprojektering via MCP och HTTP. Varje design arbetas fram för det land där byggnaden står: material som går att använda där, produkter som tillverkarna faktiskt säljer där, och den tekniska uppbyggnaden bakom ytan. En rendering visar det på fotot av huset, kostnadsuppskattningen prissätter det rad för rad, och PDF-albumet dokumenterar det för laget som bygger. Varje sökväg nedan är en befintlig GetFacade-endpoint, samma som iOS-, Android- och webbappen anropar. En agentnyckel begränsar bara vem som får anropa den, mäter vad den spenderar och stannar vid sitt tak.
- Bas-URL
- https://api.getfacade.ai/api/v1
- Autentisering
- Bearer <agent key>
- Paket
- @getfacade/mcp
- Körmiljö
- Node.js 20+
- Transport
- stdio (MCP), HTTPS (REST)
- Specifikation
- OpenAPI 3.1, v1.0.0
Snabbstart
Skapa en nyckel
app.getfacade.aiKontoInställningarAPISkapa nyckel
Värdet visas en gång och går inte att återskapa, bara ersätta. Utgiftstaket sätts när nyckeln skapas och gäller vid varje betald anropning.
Skapa en agentnyckelRegistrera MCP-servern
En post i klientens konfiguration, sedan omstart av klienten. Claude Desktop håller den i claude_desktop_config.json; varje annan MCP-klient tar samma tre fält.
{ "mcpServers": { "getfacade": { "command": "npx", "args": ["-y", "@getfacade/mcp"], "env": { "GETFACADE_API_KEY": "your-key" } } } }Miljövariabler Variabel Obligatorisk Standardvärde GETFACADE_API_KEYJa —GETFACADE_API_BASE_URLNej https://api.getfacade.ai/api/v1Eller anropa HTTP-API:t direkt
Samma nyckel fungerar som bearer-token. Anrop och svar är JSON:API-dokument, där id är ett fält på toppnivå och aldrig ligger inne i attributes.
curl -X POST https://api.getfacade.ai/api/v1/projects \ -H "Authorization: Bearer $GETFACADE_API_KEY" \ -H "Content-Type: application/json" \ -d '{"data":{"type":"project","attributes":{"name":"Maple Street 14"}}}'
Verktyg
Tjugoett verktyg. MCP-servern håller inget tillstånd och inga egna regler: varje verktyg är ett eller flera anrop till de endpoints som står bredvid, och varje meddelande agenten återger är skrivet av API:t.
create_buildingcreate_building(name, goals?, construction_region?) -> { building_id, name }Skapar en byggnad. Namnet är unikt inom kontot och högst 50 tecken; en dubblett avvisas med 422.
Anropar
POST /projectsupload_photoupload_photo(building_id, file_path, wait_for_validation? = true) -> { view_id, validation: { status, reason? } }Registrerar en vy, laddar upp byten till en försignerad URL, bekräftar dem och pollar tills fotot godtas eller avvisas. Bredd, höjd och md5 beräknas lokalt; bildförhållandet härleder servern.
Anropar
POST /projects/{project}/angles → PUT (presigned) → POST /angles/{angle}/confirm → GET /angles/{angle}/validationstart_designasynkronstart_design(building_id, view_id, prompt?, style_ids?, colors?, brand_selections?, render_effort?, seed?) -> { design_id, job_id, status, seed }Projekterar fasaden på en vald vy och visar den på fotot: material som går att använda i byggnadens land, produkter som faktiskt säljs där och uppbyggnaden bakom ytan. Skapar en design, köar arbetet och returnerar jobb-id. Seed är valfritt: utelämnas det genererar servern ett och returnerar det.
Anropar
POST /projects/{project}/concepts → POST /concepts/{concept}/angles/{conceptAngle}/rendersrefine_designasynkronrefine_design(render_id | design_id + building_id, instruction, style_ids?, colors?, brand_selections?, render_effort?, seed?) -> { design_id, job_id, status, parent_render_id, seed }Reviderar en färdig design i ord. Instruktionen tillämpas på den färdiga designen, så allt den inte nämner behålls. Att revidera en huvudvy skapar en ny design, så den tidigare skrivs aldrig över.
Anropar
GET /renders/{render} → POST /concepts/{concept}/angles/{conceptAngle}/renders (mode: refine)get_jobget_job(job_id, kind: "render" | "album" | "estimate" = "render") -> { status, expected_seconds?, result_url?, error?, error_code? }Läser tillståndet för en rendering, kalkyl eller ett album.
Anropar
GET /renders/{render} · GET /estimates/{estimate}list_jobslist_jobs(kind?, limit? = 20) -> [{ job_id, kind, status, building_id, created_at }]Senaste jobben i kontot, oavslutade först.
Anropar
GET /historylist_designslist_designs(building_id) -> [{ design_id, note, has_main_render, main_render_id, main_render_url, renders }]Byggnadens gestaltningar med sina renderingar. Härifrån kommer renderings-id:n för kalkyl och album.
Anropar
GET /projects/{project}/conceptsorder_estimateasynkronorder_estimate(design_id, render_ids, currency?, measurement_system?, special_requirements?) -> { job_id, status }Prissätter designen rad för rad, i material och arbete, till vad de angivna materialen kostar i byggnadens land. Valuta och måttsystem följer som standard det landet.
Anropar
POST /projects/{project}/concepts/{concept}/estimatesorder_albumasynkronorder_album(design_id, render_ids, language?, include_blueprints?, include_estimate?, requirements?) -> { job_id, status }Dokumenterar designen för laget som bygger: materialen, fasadens uppbyggnad, säkerhetsnoteringar och normerna bakom dem. Kräver en färdig huvudrendering.
Anropar
POST /concepts/{concept}/album/generateupscale_renderasynkronupscale_render(render_id) -> { job_id, status }Förstorar en färdig rendering. Kostar krediter och körs asynkront.
Anropar
POST /renders/{render}/upscaleget_estimateget_estimate(estimate_id) -> { status, currency, facade_area, materials_total, labor_total, grand_total, notes, lines: [{ line_id, section, name, quantity, unit, unit_price, line_total }] }Själva kalkylen: summor, antagandena bakom dem och varje rad med mängd, enhet och pris. get_job rapporterar en kalkyls status, aldrig dess innehåll.
Anropar
GET /estimates/{estimate}add_estimate_lineadd_estimate_line(estimate_id, section, name, quantity, unit_price, unit?, category?) -> { line_id }Lägger till en rad i kalkylen. Enheterna kommer från kalkylens eget måttsystem.
Anropar
POST /estimates/{estimate}/itemsupdate_estimate_lineupdate_estimate_line(estimate_id, line_id, name?, quantity?, unit_price?, unit?, category?, section?) -> { line_id }Ändrar en rad i kalkylen. Bara skickade fält ändras; servern räknar om summorna.
Anropar
PATCH /estimates/{estimate}/items/{item}delete_estimate_linedelete_estimate_line(estimate_id, line_id) -> { deleted }Tar bort en rad ur kalkylen.
Anropar
DELETE /estimates/{estimate}/items/{item}delete_renderdelete_render(render_id) -> { deleted }Raderar en rendering. Raderas huvudrenderingen går dess design tillbaka till utkast.
Anropar
DELETE /renders/{render}delete_designdelete_design(building_id, design_id) -> { deleted }Raderar en design med renderingarna under den.
Anropar
DELETE /projects/{project}/concepts/{concept}delete_buildingdelete_building(building_id) -> { deleted }Raderar en byggnad med allt i den. Redan spenderade krediter betalas inte tillbaka.
Anropar
DELETE /projects/{project}list_token_packageslist_token_packages() -> [{ package, tokens, price, currency }]Paketen kontot kan köpa, med pris och antal krediter.
Anropar
GET /tokens/packagesbuy_tokensasynkronbuy_tokens(package) -> { status, transaction_id, tokens, checkout_url?, detail }Köper ett paket till den här nyckelns plånbok. Kräver en nyckel utfärdad med köp påslaget och går aldrig utöver vad nyckeln fortfarande får spendera.
Anropar
POST /tokens/purchaseget_balanceget_balance() -> { balance, scope: "api", spend_cap, spent, remaining, is_admissible }Agentplånbok, nyckelns tak och om nästa betalda anrop kommer att släppas igenom.
Anropar
GET /tokens/balancereport_problemreport_problem(message, category?, context?: { tool, endpoint, status_code, job_id, expected, actual }) -> { reference, message }Rapporterar ett fel i detta API: ett fält som beskrivs här men aldrig kommer, ett avslag vars formulering inte visar vägen vidare, ett resultat som inte motsvarar beställningen. Gratis och tas emot med tom plånbok; tillbaka kommer en referens, inte ett svar.
Anropar
POST /feedback
Autentisering och nycklar
- Nyckeln färdas som bearer-token i
Authorization-huvudet. MCP-servern läser den urGETFACADE_API_KEYoch skickar inget annat. - Värdet visas en gång, när nyckeln skapas, och bara dess hash sparas. Rotation innebär att skapa en ny nyckel och återkalla den gamla.
- Varje nyckel bär ett utgiftstak som tillämpas på servern innan anropet når en controller. Ett nått tak stoppar den nyckeln, inte kontot.
- Nycklar hanterar inte nycklar: det är en mänsklig handling, och de endpointerna svarar 403 på en agentnyckel.
- Återkallning gäller omedelbart. Anrop med en återkallad nyckel svarar 401.
Asynkront arbete och pollning
start_design,order_estimateochorder_albumreturnerar ett jobb-id och är därmed klara. En rendering tar minuter: pollaGET /renders/{render}ellerGET /estimates/{estimate}tills tillståndet är slutgiltigt.- Att fotogranskningen är klar meddelas över en websocket som en agent inte har. Polla
GET /angles/{angle}/validationoch läsvalidation.is_in_progress; härled inte slutgiltigheten själv ur statustexten. - En färdig rendering och ett färdigt album ligger på permanenta publika URL:er: utan signatur och utan utgångstid. Länken kan ges direkt till en person, som svar på ”visa mig resultatet”. Eftersom den inte är signerad frågar den ingen om lov: den fortsätter fungera för var och en som får den och går inte att återkalla.
GET /renders/{render}/downloadär något annat: en signerad URL som går ut inom minuter och bär ett filnamn. Den är till för att spara filen, inte för att dela den.
Hastighetsgränser per nyckel
En agentnyckel har egna kvoter, skilda från de mänskliga sessionerna på samma konto, så att en agent i loop inte äter upp kvoten för personen framför skärmen. Avslaget är billigt: det fattas i mellanvaran, före allt databasarbete.
| Område | Per minut | Per timme |
|---|---|---|
| Läsningar och vanliga skrivningar | 120 | 2000 |
| Status- och granskningspollning | 120 | 2000 |
| Beställning av rendering, kalkyl och album | 10 | 200 |
Idempotens
Ett betalt anrop skapar ett jobb, och debiteringen följer jobbet. Att namnge anropet är det som låter en upprepning returnera samma jobb i stället för att skapa ett andra.
Idempotency-Keykrävs i varje betalt anrop med en API-nyckel: starta eller finjustera en design, förstora en render, beställa en kostnadsberäkning eller ett album, göra om en beräkning. Utan den svarar anropet 422IDEMPOTENCY_KEY_REQUIRED, och ingenting köas.- Vilket värde som helst på 8 till 191 tecken, ett per beställning; vanligen ett UUID. En ny beställning får ett nytt värde: två identiska anrop under två värden är två designer.
- Att upprepa ett anrop med samma värde och samma body ger tillbaka ursprunglig status och body, med
Idempotent-Replay: truei svaret. Ingenting köas och ingenting debiteras två gånger. - Samma värde med en annan body svarar 422
IDEMPOTENCY_KEY_REUSED. En upprepning som kommer medan det första anropet fortfarande pågår svarar 409IDEMPOTENCY_IN_PROGRESS: vänta och skicka samma anrop igen. - Varje 4xx frigör värdet, så samma värde kan skickas igen när orsaken är åtgärdad. Värden minns i 24 timmar, per konto.
@getfacade/mcpskapar värdet och gör om anropet under det på egen hand, så ett verktygsanrop behöver inte skicka något.
Fel
Fel kommer som JSON:API-feldokument. Laravels valideringssvar har inte JSON:API-form och bär sin text i message.
| Status | Kod | Innebörd | Går att upprepa |
|---|---|---|---|
401 | — | Nyckeln saknas, är återkallad eller har gått ut. | Nej |
402 | AGENT_CREDITS_EXHAUSTED | Kontot har inga krediter kvar i api-omfånget. | Nej |
402 | AGENT_KEY_CAP_REACHED | Den här nyckeln har förbrukat sitt tak. Skapa en ny nyckel eller höj taket. | Nej |
403 | — | Den här endpointen är inte tillgänglig för API-nycklar. Agent-API:et omfattar byggnader, foton, designer, renderingar, kalkyler, album och API-plånboken. Inställningar för konto, inloggning och betalning ändras av en person som är inloggad i appen. | Nej |
403 | AGENT_PURCHASE_NOT_ALLOWED | Den här nyckeln utfärdades utan rätt att köpa krediter. | Nej |
403 | AGENT_PURCHASE_EXCEEDS_CAP | Köpet skulle föra nyckeln förbi dess utgiftstak. | Nej |
409 | IDEMPOTENCY_IN_PROGRESS | Det första anropet med den här Idempotency-Key har inte svarat än. Vänta och skicka samma anrop igen. | Ja |
422 | — | Anropet förstods och avvisades: dubblerat byggnadsnamn, avvisat foto, album beställt innan huvudrenderingen blev klar. | Nej |
422 | IDEMPOTENCY_KEY_REQUIRED | Ett betalt anrop med API-nyckel utan Idempotency-Key-rubrik. Ingenting köades; skicka det igen med rubriken. | Nej |
422 | IDEMPOTENCY_KEY_REUSED | Den här Idempotency-Key har använts för en annan begäran. Använd ett nytt värde för en ny beställning. | Nej |
429 | — | Nyckelns egen kvot är slut. Backa av, upprepa inte i tät loop. | Ja |
Den läsbara texten skrivs av API:t, på anroparens språk. Visa errors[].detail som den står i stället för att formulera ett eget meddelande.
Betalning och tillträde
- Betalda anrop dras från krediter i
api-scopet, och antagningen tittar bara på det saldot: varje nyckel betalar i krediter. - Ett aktivt Pro Plan fyller
api-plånboken till 1 000 krediter en gång per faktureringsperiod. Därutöver köps krediter. - En nyckel fyller på sin egen plånbok bara om den utfärdats med köp påslaget, och högst med det den fortfarande får spendera, så ett köp höjer aldrig utgiftstaket.
api-omfånget är en egen plånbok. Appens krediter, gratisnivån inräknad, förbrukas aldrig av en nyckel.- Förbrukningen räknas per nyckel, så varje assistents konsumtion syns för sig.
- Förhandskontrollen är
GET /tokens/balance, fältetdata.attributes.agent.is_admissible. Blocket finns bara för agentnycklar, och flaggan speglar tillträdesmellanvaran exakt. Läs den i stället för att själv jämföra saldo med tak. - Tillträdet avgörs innan arbete köas, så ett avvisat anrop kostar ingenting.
Färg- och varumärkestoken
start_design tar två oberoende listor med högst tio poster vardera. Ordningen bär rollen 60/30/10: första posten är den dominerande väggfärgen.
colors
| Token | Innebörd |
|---|---|
palette:1 | Ett kurerat GetFacade-schema, via id. |
#8A8F7D | En fri färg, sex hexadecimala tecken. |
paint:412 | En tillverkarkulör, i den tvådelade formen som behålls för bakåtkompatibilitet. |
brand_selections
| Token | Innebörd |
|---|---|
siding:brand:12 | Vilken produkt som helst från den tillverkaren i den kategorin. |
siding:line:40@double-4-dutchlap | En serie, på en geometri. |
siding:product:88@double-4-dutchlap | En produkt, fullt bestämd. |
paint:brand:3 | Vilken kulör som helst från det färgmärket. |
paint:product:412 | En enskild färgkulör. |
Grammatiken är category:level:id[@value][.value]. Delen efter @ bär sluggar för geometrivärden, unika inom sin kategori, så axeln de hör till slås upp i stället för att skrivas ut i token. En okänd token avvisas med 422 och förbigås aldrig tyst.
Session från början till slut
En byggnad, ett foto, en gestaltning och sedan de två dokumenten. Instruktionen som ger det:
Skapa en byggnad som heter Maple Street 14, ladda upp ./front.jpg som dess vy och starta en gestaltning med varmgrå väggar och vita foder. Beställ kalkylen och albumet för resultatet.
create_building(name: "Maple Street 14")
-> { building_id: "0f8c…" }
upload_photo(building_id: "0f8c…", file_path: "./front.jpg")
-> { view_id: "41ab…", validation: { status: "approved" } }
start_design(building_id: "0f8c…", view_id: "41ab…",
colors: ["#8A8F7D", "#F2F0EB"],
brand_selections: ["siding:line:40@double-4-dutchlap"])
-> { design_id: "7d21…", job_id: "b933…", status: "queued" }
get_job(job_id: "b933…")
-> { status: "completed", result_url: "https://…" }
refine_design(render_id: "b933…",
instruction: "put a canopy over the front door")
-> { design_id: "9e44…", job_id: "c07f…", status: "queued" }
order_estimate(design_id: "9e44…", render_ids: ["c07f…"])
order_album(design_id: "9e44…", render_ids: ["c07f…"], include_estimate: true)