GetFacade agent-API
Gevelontwerp via MCP en HTTP. Elk ontwerp wordt uitgewerkt voor het land waar het gebouw staat: materialen die daar toepasbaar zijn, producten die fabrikanten daar echt verkopen, en de technische opbouw achter het oppervlak. Een render laat het zien op de foto van het huis, de kostenraming zet er regel voor regel een prijs op, en het pdf-album legt het vast voor de ploeg die het uitvoert. Elk pad hieronder is een bestaand GetFacade-endpoint, hetzelfde dat de iOS-, Android- en web-app aanroepen. Een agentsleutel beperkt alleen wie het mag aanroepen, meet wat er wordt uitgegeven en stopt bij het plafond.
getfacade/mcpMIT- Basis-URL
- https://api.getfacade.ai/api/v1
- Authenticatie
- Bearer <agent key>
- Pakket
- @getfacade/mcp
- Runtime
- Node.js 20+
- Transport
- stdio (MCP), HTTPS (REST)
- Specificatie
- OpenAPI 3.1, v1.0.0
Snelstart
Maak een sleutel aan
app.getfacade.aiAccountInstellingenAPISleutel aanmaken
De waarde wordt één keer getoond en is niet te herstellen, alleen te vervangen. De bestedingslimiet wordt bij het aanmaken ingesteld en geldt bij elke betaalde aanroep.
Agentsleutel aanmakenRegistreer de MCP-server
Eén regel in de clientconfiguratie, daarna de client herstarten. Claude Desktop bewaart die in claude_desktop_config.json; elke andere MCP-client neemt dezelfde drie velden.
{ "mcpServers": { "getfacade": { "command": "npx", "args": ["-y", "@getfacade/mcp"], "env": { "GETFACADE_API_KEY": "your-key" } } } }Omgevingsvariabelen Variabele Verplicht Standaardwaarde GETFACADE_API_KEYJa —GETFACADE_API_BASE_URLNee https://api.getfacade.ai/api/v1Of roep de HTTP-API rechtstreeks aan
Dezelfde sleutel werkt als bearer-token. Verzoeken en antwoorden zijn JSON:API-documenten, waarin id een veld op het hoogste niveau is en nooit in attributes staat.
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"}}}'
Tools
Eenentwintig tools. De MCP-server houdt geen staat bij en heeft geen eigen regels: elke tool is een of meer aanroepen naar de endpoints ernaast, en elk bericht dat de agent doorgeeft komt van de API.
create_buildingcreate_building(name, goals?, construction_region?) -> { building_id, name }Maakt een gebouw aan. De naam is uniek binnen het account en maximaal 50 tekens; een duplicaat wordt geweigerd met 422.
Roept aan
POST /projectsupload_photoupload_photo(building_id, file_path, wait_for_validation? = true) -> { view_id, validation: { status, reason? } }Registreert een aanzicht, uploadt de bytes naar een vooraf ondertekende URL, bevestigt ze en pollt tot de foto is geaccepteerd of geweigerd. Breedte, hoogte en md5 worden lokaal berekend; de beeldverhouding leidt de server af.
Roept aan
POST /projects/{project}/angles → PUT (presigned) → POST /angles/{angle}/confirm → GET /angles/{angle}/validationstart_designasynchroonstart_design(building_id, view_id, prompt?, style_ids?, colors?, brand_selections?, render_effort?, seed?) -> { design_id, job_id, status, seed }Ontwerpt de gevel op een gekozen aanzicht en laat het zien op de foto: materialen die in het land van het gebouw toepasbaar zijn, producten die daar echt verkocht worden en de opbouw achter het oppervlak. Maakt een ontwerp aan, zet het werk in de wachtrij en geeft het taak-id terug. De seed is optioneel: laat je hem weg, dan genereert de server er een en geeft die terug.
Roept aan
POST /projects/{project}/concepts → POST /concepts/{concept}/angles/{conceptAngle}/rendersrefine_designasynchroonrefine_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 }Herziet een afgerond ontwerp in woorden. De instructie wordt op het afgeronde ontwerp toegepast, dus alles wat niet genoemd wordt blijft staan. Het herzien van een hoofdaanzicht maakt een nieuw ontwerp, zodat het eerdere nooit wordt overschreven.
Roept aan
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? }Leest de stand van één render, kostenraming of album.
Roept aan
GET /renders/{render} · GET /estimates/{estimate}list_jobslist_jobs(kind?, limit? = 20) -> [{ job_id, kind, status, building_id, created_at }]Recente taken van het account, onafgeronde eerst.
Roept aan
GET /historylist_designslist_designs(building_id) -> [{ design_id, note, has_main_render, main_render_id, main_render_url, renders }]Ontwerpen van een gebouw met hun renders. Hier komen de render-id's vandaan voor een raming of een album.
Roept aan
GET /projects/{project}/conceptsorder_estimateasynchroonorder_estimate(design_id, render_ids, currency?, measurement_system?, special_requirements?) -> { job_id, status }Zet regel voor regel een prijs op het ontwerp, in materiaal en arbeid, tegen wat de genoemde materialen kosten in het land van het gebouw. Valuta en maatstelsel volgen standaard dat land.
Roept aan
POST /projects/{project}/concepts/{concept}/estimatesorder_albumasynchroonorder_album(design_id, render_ids, language?, include_blueprints?, include_estimate?, requirements?) -> { job_id, status }Legt het ontwerp vast voor de ploeg die het uitvoert: de materialen, de opbouw van de gevel, veiligheidsnotities en de normen daarachter. Vereist een afgeronde hoofdrender.
Roept aan
POST /concepts/{concept}/album/generateupscale_renderasynchroonupscale_render(render_id) -> { job_id, status }Vergroot een afgeronde render. Kost tegoed en verloopt asynchroon.
Roept aan
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 }] }De calculatie zelf: totalen, de aannames erachter en elke regel met hoeveelheid, eenheid en prijs. get_job meldt de status van een calculatie, nooit de inhoud.
Roept aan
GET /estimates/{estimate}add_estimate_lineadd_estimate_line(estimate_id, section, name, quantity, unit_price, unit?, category?) -> { line_id }Voegt een regel toe aan de begroting. De eenheden komen uit haar eigen maatsysteem.
Roept aan
POST /estimates/{estimate}/itemsupdate_estimate_lineupdate_estimate_line(estimate_id, line_id, name?, quantity?, unit_price?, unit?, category?, section?) -> { line_id }Wijzigt een regel van de begroting. Alleen meegegeven velden veranderen; de server rekent de totalen opnieuw.
Roept aan
PATCH /estimates/{estimate}/items/{item}delete_estimate_linedelete_estimate_line(estimate_id, line_id) -> { deleted }Verwijdert een regel uit de begroting.
Roept aan
DELETE /estimates/{estimate}/items/{item}delete_renderdelete_render(render_id) -> { deleted }Verwijdert een render. Verwijder je de hoofdrender, dan gaat het ontwerp terug naar concept.
Roept aan
DELETE /renders/{render}delete_designdelete_design(building_id, design_id) -> { deleted }Verwijdert een ontwerp met de renders eronder.
Roept aan
DELETE /projects/{project}/concepts/{concept}delete_buildingdelete_building(building_id) -> { deleted }Verwijdert een gebouw met alles erin. Al besteed tegoed wordt niet terugbetaald.
Roept aan
DELETE /projects/{project}list_token_packageslist_token_packages() -> [{ package, tokens, price, currency }]De pakketten die dit account kan kopen, met prijs en aantal tegoeden.
Roept aan
GET /tokens/packagesbuy_tokensasynchroonbuy_tokens(package) -> { status, transaction_id, tokens, checkout_url?, detail }Koopt één pakket voor de portemonnee van deze sleutel. Vereist een sleutel met koopmogelijkheid en gaat nooit verder dan wat de sleutel nog mag uitgeven.
Roept aan
POST /tokens/purchaseget_balanceget_balance() -> { balance, scope: "api", spend_cap, spent, remaining, is_admissible }Agentportemonnee, de limiet van deze sleutel en of de volgende betaalde aanroep wordt toegelaten.
Roept aan
GET /tokens/balancereport_problemreport_problem(message, category?, context?: { tool, endpoint, status_code, job_id, expected, actual }) -> { reference, message }Meldt een fout in deze API: een veld dat hier beschreven staat maar nooit aankomt, een weigering waarvan de formulering geen weg vooruit geeft, een resultaat dat niet klopt met de vraag. Gratis en ook met een leeg saldo aanvaard; terug komt een referentie, geen antwoord.
Roept aan
POST /feedback
Authenticatie en sleutels
- De sleutel reist als bearer-token in de
Authorization-header. De MCP-server leest hem uitGETFACADE_API_KEYen stuurt niets anders mee. - De waarde wordt één keer getoond, bij het aanmaken, en alleen de hash wordt bewaard. Roteren betekent een nieuwe sleutel aanmaken en de oude intrekken.
- Elke sleutel draagt een bestedingslimiet, die aan de serverkant geldt voordat een aanroep een controller bereikt. Een bereikte limiet stopt die sleutel, niet het account.
- Sleutels beheren geen sleutels: dat is een menselijke handeling, en die endpoints antwoorden een agentsleutel met 403.
- Intrekken werkt onmiddellijk. Aanroepen met een ingetrokken sleutel antwoorden 401.
Asynchroon werk en pollen
start_design,order_estimateenorder_albumgeven een taak-id terug en zijn daarmee klaar. Een render duurt minuten: pollGET /renders/{render}ofGET /estimates/{estimate}tot de staat definitief is.- Het einde van de fotovalidatie wordt gemeld via een websocket die een agent niet heeft. Poll
GET /angles/{angle}/validationen leesvalidation.is_in_progress; leid de eindtoestand niet zelf af uit de statustekst. - Een afgeronde render en een afgerond album staan op permanente publieke URL's: zonder handtekening en zonder vervaldatum. De link kan rechtstreeks aan iemand worden gegeven, als antwoord op “laat het resultaat zien”. Omdat hij niet ondertekend is, vraagt hij niemand om toestemming: hij blijft werken voor iedereen die hem ontvangt en is niet in te trekken.
GET /renders/{render}/downloadis iets anders: een ondertekende URL die binnen minuten verloopt en een bestandsnaam meedraagt. Bedoeld om het bestand op te slaan, niet om het te delen.
Snelheidslimieten per sleutel
Een agentsleutel heeft eigen tellers, gescheiden van de menselijke sessies van hetzelfde account, zodat een agent in een lus niet het quotum opeet van de persoon achter het scherm. Weigeren is goedkoop: het gebeurt in de middleware, vóór enig databasewerk.
| Bereik | Per minuut | Per uur |
|---|---|---|
| Lezen en gewoon schrijven | 120 | 2000 |
| Status- en validatiepolling | 120 | 2000 |
| Bestellingen van render, raming en album | 10 | 200 |
Idempotentie
Een betaalde aanroep maakt een taak aan, en de kosten volgen de taak. Het benoemen van de aanroep is wat een herhaling dezelfde taak laat teruggeven in plaats van een tweede aan te maken.
Idempotency-Keyis verplicht bij elke betaalde aanroep met een API-sleutel: een ontwerp starten of bijwerken, een render vergroten, een begroting of album bestellen, een begroting opnieuw genereren. Zonder de header antwoordt de aanroep met 422IDEMPOTENCY_KEY_REQUIREDen wordt er niets in de wachtrij gezet.- Elke waarde van 8 tot 191 tekens, één per opdracht; meestal een UUID. Een nieuwe opdracht krijgt een nieuwe waarde: twee identieke aanroepen met twee waarden zijn twee ontwerpen.
- Een aanroep herhalen met dezelfde waarde en dezelfde body geeft de oorspronkelijke status en body terug, met
Idempotent-Replay: truein het antwoord. Er wordt niets in de wachtrij gezet en niets dubbel in rekening gebracht. - Dezelfde waarde met een andere body antwoordt met 422
IDEMPOTENCY_KEY_REUSED. Een herhaling die binnenkomt terwijl de eerste aanroep nog loopt, antwoordt met 409IDEMPOTENCY_IN_PROGRESS: wacht en stuur dezelfde aanroep opnieuw. - Elke 4xx geeft de waarde vrij, dus dezelfde kan opnieuw worden gestuurd zodra de oorzaak is verholpen. Waarden worden 24 uur onthouden, per account.
@getfacade/mcpmaakt de waarde zelf aan en herhaalt de aanroep ermee, dus in de tool-aanroep hoef je niets mee te geven.
Fouten
Mislukkingen komen als JSON:API-foutdocumenten. Validatieantwoorden van Laravel hebben die vorm niet en dragen hun tekst in message.
| Status | Code | Betekenis | Herhaalbaar |
|---|---|---|---|
401 | — | De sleutel ontbreekt, is ingetrokken of verlopen. | Nee |
402 | AGENT_CREDITS_EXHAUSTED | Het account heeft geen api-tegoed meer. | Nee |
402 | AGENT_KEY_CAP_REACHED | Deze sleutel heeft zijn limiet opgebruikt. Maak een andere sleutel aan of verhoog de limiet. | Nee |
403 | — | Dit endpoint is niet beschikbaar voor API-sleutels. De agent-API omvat gebouwen, foto's, ontwerpen, renders, begrotingen, albums en de API-portemonnee. Account-, inlog- en betaalinstellingen wijzigt een persoon die is ingelogd in de app. | Nee |
403 | AGENT_PURCHASE_NOT_ALLOWED | Deze sleutel is aangemaakt zonder recht om tegoed te kopen. | Nee |
403 | AGENT_PURCHASE_EXCEEDS_CAP | De aankoop zou de sleutel over haar bestedingsplafond tillen. | Nee |
409 | IDEMPOTENCY_IN_PROGRESS | De eerste aanroep met deze Idempotency-Key heeft nog niet geantwoord. Wacht en stuur dezelfde aanroep opnieuw. | Ja |
422 | — | Het verzoek is begrepen en geweigerd: dubbele gebouwnaam, afgewezen foto, album besteld voordat de hoofdrender klaar was. | Nee |
422 | IDEMPOTENCY_KEY_REQUIRED | Een betaalde aanroep met API-sleutel zonder Idempotency-Key-header. Er is niets in de wachtrij gezet; stuur hem opnieuw mét header. | Nee |
422 | IDEMPOTENCY_KEY_REUSED | Deze Idempotency-Key is voor een ander verzoek gebruikt. Gebruik een nieuwe waarde voor een nieuwe opdracht. | Nee |
429 | — | De eigen teller van deze sleutel is op. Wacht even, herhaal niet in een strakke lus. | Ja |
De leesbare tekst schrijft de API, in de taal van de aanroeper. Toon errors[].detail ongewijzigd in plaats van een eigen bericht op te stellen.
Facturering en toelating
- Betaalde aanroepen putten uit
api-scope credits, en de toelating kijkt alleen naar dat saldo: elke sleutel betaalt in credits. - Een actief Pro Plan vult de
api-wallet eens per factuurperiode aan tot 1.000 credits. Daarboven worden credits gekocht. - Een sleutel vult haar eigen portemonnee alleen aan als ze met koopmogelijkheid is aangemaakt, en niet meer dan ze nog mag uitgeven, dus een aankoop tilt het bestedingsplafond nooit op. Het antwoord meldt
chargedals de opgeslagen betaalmethode dekte, ofrequires_humanmet een betaallink die een mens opent. - De
api-scope is een aparte portemonnee. De credits van de app, inclusief de gratis laag, worden nooit door een sleutel uitgegeven. - Al betaalde credits uit de app gaan via het API-paneel naar de
api-portemonnee, op het web en in beide mobiele apps. Gratis credits blijven waar ze zijn, en de overdracht gaat maar één kant op. - Uitgaven worden per sleutel geteld, zodat het verbruik van elke assistent apart zichtbaar is.
- De voorafgaande controle is
GET /tokens/balance, velddata.attributes.agent.is_admissible. Het blok verschijnt alleen bij agentsleutels en de vlag spiegelt de toelatings-middleware exact. Lees hem in plaats van zelf saldo en limiet te vergelijken. - Toelating wordt beslist voordat werk in de wachtrij gaat, dus een geweigerde aanroep kost niets.
Kleur- en merktokens
start_design neemt twee onafhankelijke lijsten van maximaal tien items. De volgorde draagt de 60/30/10-rol: het eerste item is de dominante muurkleur.
colors
| Token | Betekenis |
|---|---|
palette:1 | Een samengesteld GetFacade-schema, op id. |
#8A8F7D | Een vrije kleur, zes hexadecimale tekens. |
paint:412 | Een fabrikantstaal, in de tweedelige vorm die om compatibiliteitsredenen blijft. |
brand_selections
| Token | Betekenis |
|---|---|
siding:brand:12 | Elk product van die fabrikant in die categorie. |
siding:line:40@double-4-dutchlap | Eén lijn, op één geometrie. |
siding:product:88@double-4-dutchlap | Eén product, volledig bepaald. |
paint:brand:3 | Elke kleur van dat verfmerk. |
paint:product:412 | Eén verfstaal. |
De grammatica is category:level:id[@value][.value]. Het deel na @ draagt slugs van geometriewaarden, die uniek zijn binnen hun categorie, zodat de bijbehorende as wordt opgezocht in plaats van uitgeschreven. Een onbekend token wordt geweigerd met 422 en nooit stilzwijgend genegeerd.
Volledige sessie
Eén gebouw, één foto, één ontwerp en dan de twee documenten. De opdracht die dat oplevert:
Maak een gebouw met de naam Maple Street 14, upload ./front.jpg als aanzicht en start een ontwerp met warmgrijze muren en witte lijsten. Bestel de kostenraming en het album voor het resultaat.
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)