Skip to content
Connect an agent
Patterns

Draw from pattern

Fill a pattern and draw it.

POST/v1/patterns/draw

TL;DR

QuestionAnswer
What does it do?Fill a pattern and draw it.
Which tool does the same?draw_from_pattern
What does it take?A JSON body of type DrawFromPatternInput.
What does it return?Status 200 with a body of type DrawFromPatternResponse.
What can go wrong?400 the body failed schema validation; 401 the api key is missing or not valid; 403 the account is on the free plan, which does not include the rest drawing and checking routes (plan.rest_not_included); 413 the body is larger than the size cap; 429 too many requests. Every failure uses the one error envelope.

What it does

Fills a pattern for a flavour with the slot values you send, validates the result, and returns the source, the slots, the advice on adapting it, the quality warnings, a plain-text outline, the natural size, and the SVG for the light theme, the dark theme, or both. An unknown id, flavour, or slot, or a value with a quote in it, is a normal 200 result with found false and every problem with its code and a hint, never an error. Prefer this route over calling the get route and then the draw, validate, outline, and render routes when a pattern fits as it is and only names change.

Request body

The body has the type DrawFromPatternInput.

FieldTypeRequiredDescription
idstringyesThe pattern id, as find_pattern returns it, such as three-tier-network. at least 1 character; at most 60 characters.
provider"neutral" | "aws" | "azure" | "gcp"noneutral (generic glyphs, no vendor names; the default), or aws, azure, or gcp for that provider's icons. Not every pattern comes in every flavour; the answer lists the ones it has. default "neutral".
slotsobjectnoSlot values keyed by slot id, such as {"office": "Branch office"}: plain text of up to 60 characters, no quotes or line breaks. Omit a slot to keep its default. get_pattern lists the slots and what they mean.
themes"light" | "dark" | "both"nolight, dark, or both (the default): the light picture and the dark one a dark page needs. default "both".
detail"summary" | "full"nosummary (the default), or full: the whole outline, and the source embedded in each SVG. default "summary".
svg"auto" | "always" | "never"noauto (the default) returns the SVGs, but over MCP leaves them out when the answer would be too big for a client (picturesOmitted). always returns them at any size. never draws nothing, which is cheaper. The HTTP API treats auto as always. default "auto".
embedSourcebooleannoWrite the source into each SVG so read_diagram can give it back. Set it when you save the SVG in a repository or publish it to edit later; anyone with the file or link can then read the source. default false.
settingsobjectnoThe repo's plotwork.config.json, if any. Schema: https://docs.plotwork.dev/schemas/plotwork.config.json (opens in a new tab).

Responses

StatusMeaningBody
200The filled pattern with its check and pictures, or the problems that stopped it.DrawFromPatternResponse
400The body failed schema validation.ErrorResponse
401The API key is missing or not valid.ErrorResponse
403The account is on the Free plan, which does not include the REST drawing and checking routes (plan.rest_not_included).ErrorResponse
413The body is larger than the size cap.ErrorResponse
429Too many requests.ErrorResponse

Response body

A 200 answer has the type DrawFromPatternResponse.

FieldTypeRequiredDescription
foundbooleanyesTrue when the pattern and flavour exist and the slot values are usable. When false, problems says why and nothing else is filled.
idstringyesThe pattern id that was asked for.
titlestring | nullyes
patternSummarystring | nullyesOne sentence: what the pattern shows.
whenToUsestring | nullyes
kindstring | nullyesA diagram kind: flow, sequence, schema, git, gantt, class, state, timeline, journey, mindmap, treemap, pie, quadrant, layers, c4, matrix, sankey, xychart, tree, or swimlane today. Later versions add kinds, so expect others.
flavour"neutral" | "aws" | "azure" | "gcp" | nullyesThe flavour that was filled.
flavours("neutral" | "aws" | "azure" | "gcp")[]yesEvery flavour this pattern comes in; empty when the pattern was not found.
sourcestring | nullyesPlotwork source, valid and ready to use; null when not found.
slotsobject[]yesEvery slot the source uses, with the value it has.
slots[].idstringyesThe slot id; the key to use in slots.
slots[].valuestringyesThe text the slot has in the source: the value sent, or the default.
slots[].defaultstringyesThe default text.
slots[].meaningstringyesWhat belongs in this slot.
slots[].isDefaultbooleanyesTrue when the slot kept its default.
notesobject | nullyesHow to adapt the pattern: what to keep, what to rename, and when to split.
notes.keepstringyesWhat to leave exactly as it is.
notes.renamestringyesWhat to rename or replace, and how.
notes.splitstringyesWhen the diagram has grown too big, and where to cut it.
problemsobject[]yesMistakes in the id, the flavour, or the slot values, each with a fix. Empty when found.
problems[].code"unknown-pattern" | "unknown-flavour" | "unknown-slot" | "bad-slot-value" | "bad-source"yes
problems[].messagestringyes
problems[].hintstringyesHow to fix it.
validbooleanyesTrue when the source has no errors. When false, nothing was drawn: fix the errors and call again.
errorsDiagnostic[]yesEvery error found in one pass, each with line, column, and a hint. Empty when valid.
errors[].code"E100" | "E101" | "E110" | "E111" | "E120" | "E121" | "E122" | "E123" | "E124" | "E125" | "E130" | "E131" | "E132" | "E133" | "E134" | "E135" | "E136" | "E137" | "E138" | "E139" | "E140" | "W200" | "W201" | "W202" | "W203" | "W204" | "W205" | "W206" | "W207" | "W500" | "M100" | "M101" | "M102" | "M103" | "M104" | "M110" | "M200" | "M201" | "M202" | "M203" | "M204" | "M205" | "M206" | "M207" | "M208" | "M209" | "M210" | "M211" | "M212" | "M213" | "M214" | "M215" | "M216" | "M217" | "M218" | "E300" | "E301" | "E302" | "E303" | "E304" | "W300" | "W301" | "W302" | "W303" | "M120" | "M220" | "M221" | "M222" | "E340" | "E341" | "E342" | "E343" | "E344" | "E345" | "W320" | "W321" | "W322" | "W323" | "M240" | "M241" | "M242" | "E360" | "E361" | "E362" | "E363" | "E364" | "E365" | "E366" | "E367" | "W330" | "W331" | "W332" | "W333" | "W334" | "M250" | "M251" | "E400" | "E401" | "E402" | "E403" | "W350" | "W351" | "W352" | "W353" | "M270" | "M271" | "E420" | "E421" | "E422" | "E423" | "E424" | "W360" | "W361" | "W362" | "W363" | "W364" | "M180" | "M280" | "M281" | "M282" | "E320" | "E321" | "E322" | "E323" | "E324" | "E325" | "E326" | "E327" | "E328" | "E329" | "E330" | "W310" | "W311" | "W312" | "W313" | "W314" | "M130" | "M131" | "M132" | "M230" | "M231" | "M232" | "M233" | "M234" | "M235" | "M236" | "M237" | "M238" | "E380" | "E381" | "E382" | "E383" | "W340" | "W341" | "W342" | "W343" | "M260" | "I100" | "I101" | "I102" | "I103" | "I104" | "I105" | "I200" | "I201" | "I202" | "I203" | "I204" | "I206" | "R100" | "R101" | "R200" | "R201" | "R202" | "R203" | "R204" | "R205" | "R206" | "R207" | "S100" | "S200" | "S101" | "S102" | "S103" | "S104" | "S201" | "S202" | "S203"yesStable code to branch on; E-codes are errors, W-codes are warnings.
errors[].severity"error" | "warning"yesErrors stop rendering; warnings never do.
errors[].messagestringyesWhat is wrong, in one sentence.
errors[].lineintegeryes1-based line in the submitted source. minimum 1.
errors[].columnintegeryes1-based column in that line. minimum 1.
errors[].lengthintegeryesNumber of characters the problem covers. minimum 1.
errors[].hintstring | nullyesA concrete suggestion for fixing it, or null.
warningsDiagnostic[]yesQuality warnings for a valid diagram: too dense, too wide, text cut, unconnected nodes, and suggestions for an icon or a group type. Empty when invalid.
warnings[].code"E100" | "E101" | "E110" | "E111" | "E120" | "E121" | "E122" | "E123" | "E124" | "E125" | "E130" | "E131" | "E132" | "E133" | "E134" | "E135" | "E136" | "E137" | "E138" | "E139" | "E140" | "W200" | "W201" | "W202" | "W203" | "W204" | "W205" | "W206" | "W207" | "W500" | "M100" | "M101" | "M102" | "M103" | "M104" | "M110" | "M200" | "M201" | "M202" | "M203" | "M204" | "M205" | "M206" | "M207" | "M208" | "M209" | "M210" | "M211" | "M212" | "M213" | "M214" | "M215" | "M216" | "M217" | "M218" | "E300" | "E301" | "E302" | "E303" | "E304" | "W300" | "W301" | "W302" | "W303" | "M120" | "M220" | "M221" | "M222" | "E340" | "E341" | "E342" | "E343" | "E344" | "E345" | "W320" | "W321" | "W322" | "W323" | "M240" | "M241" | "M242" | "E360" | "E361" | "E362" | "E363" | "E364" | "E365" | "E366" | "E367" | "W330" | "W331" | "W332" | "W333" | "W334" | "M250" | "M251" | "E400" | "E401" | "E402" | "E403" | "W350" | "W351" | "W352" | "W353" | "M270" | "M271" | "E420" | "E421" | "E422" | "E423" | "E424" | "W360" | "W361" | "W362" | "W363" | "W364" | "M180" | "M280" | "M281" | "M282" | "E320" | "E321" | "E322" | "E323" | "E324" | "E325" | "E326" | "E327" | "E328" | "E329" | "E330" | "W310" | "W311" | "W312" | "W313" | "W314" | "M130" | "M131" | "M132" | "M230" | "M231" | "M232" | "M233" | "M234" | "M235" | "M236" | "M237" | "M238" | "E380" | "E381" | "E382" | "E383" | "W340" | "W341" | "W342" | "W343" | "M260" | "I100" | "I101" | "I102" | "I103" | "I104" | "I105" | "I200" | "I201" | "I202" | "I203" | "I204" | "I206" | "R100" | "R101" | "R200" | "R201" | "R202" | "R203" | "R204" | "R205" | "R206" | "R207" | "S100" | "S200" | "S101" | "S102" | "S103" | "S104" | "S201" | "S202" | "S203"yesStable code to branch on; E-codes are errors, W-codes are warnings.
warnings[].severity"error" | "warning"yesErrors stop rendering; warnings never do.
warnings[].messagestringyesWhat is wrong, in one sentence.
warnings[].lineintegeryes1-based line in the submitted source. minimum 1.
warnings[].columnintegeryes1-based column in that line. minimum 1.
warnings[].lengthintegeryesNumber of characters the problem covers. minimum 1.
warnings[].hintstring | nullyesA concrete suggestion for fixing it, or null.
summarystring | nullyesOne-line description of the diagram, usable as alt text; null when invalid.
outlinestring[]yesThe diagram as plain text in reading order, to check it says what you meant; empty when invalid.
outlineTruncatedbooleanyesTrue when the summary level cut the outline short. Call again with detail "full" to read all of it.
sizeobject | nullyesNatural size of the laid-out diagram; null when invalid.
size.widthintegeryesWidth in px. minimum 1.
size.heightintegeryesHeight in px. minimum 1.
qualityobjectnoHow clean the picture looks (score, grade, measures) and up to three changes that would help; read it instead of looking. Absent when invalid.
quality.scoreintegeryes0 to 100; 100 is a picture with nothing to fix. The same diagram always gets the same score. minimum 0; maximum 100.
quality.grade"clean" | "fair" | "cluttered"yesclean is 85 or more, fair 60 or more, cluttered below.
quality.measuresobjectyesWhat the score is made from: crossings, lineOverBox, labelOverlaps, smallestTextPx (in an 880px column), aspectRatio, emptySpace (0 to 1), longestLine (px), detour (1 is straight), the counts of boxes, lines, labels, series, and slices, and any measure the kind adds.
quality.hintsstring[]yesUp to three changes, the one worth most first, each naming the statement or option to edit.
quality.linestringyesThe grade, the score, and the first hint in one line.
noticesNote[]noInformation notes, such as an icon alias drawn as the real icon; absent when there is none.
notices[].codestringyesA stable code, such as I122 for an icon alias.
notices[].severity"info"yesA note never stops a drawing and is not a warning.
notices[].messagestringyes
notices[].lineintegeryesminimum 1.
notices[].columnintegeryesminimum 1.
notices[].lengthintegeryesminimum 1.
notices[].hintstring | nullyesThe text to write instead.
rendersobject[]yesOne picture per requested color scheme, light first; empty when invalid, when svg is never, and when every picture was left out (see picturesOmitted).
renders[].theme"light" | "dark"yesThe color scheme this picture is drawn in.
renders[].svgstringyesSelf-contained SVG markup with an accessible title and description.
renders[].sizeSizeyesNatural size of a rendered diagram in px.
renders[].size.widthintegeryesWidth in px. minimum 1.
renders[].size.heightintegeryesHeight in px. minimum 1.
picturesOmittedobjectnoPresent only when pictures were left out because the answer would have been too big for an AI client to read in one piece.
picturesOmitted.themes("light" | "dark")[]yesThe color schemes whose pictures were left out.
picturesOmitted.charactersintegeryesHow many characters the pictures left out came to.
picturesOmitted.limitintegeryesThe most characters one answer may hold before the pictures are left out.
picturesOmitted.whystringyesWhy they were left out, and what to do.
viewUrlstringnoA link that shows a valid diagram in a browser; give it to the person who wants to look. The source is in the part after #, never sent to a server, but anyone with the link can read it. Absent when too long; next says so.
pngUrlstringnoThe viewUrl with &download=png: opening it in a browser saves the diagram as a PNG for Slack, email, or a wiki. The PNG is drawn in the person's browser, not on a server, so it is a link to open, not an image address to embed. Absent when too long.
svgUrlstringnoThe viewUrl with &download=svg: a person opens it to download the SVG. Not a file address for curl; use saveCommand. Absent when too long.
saveCommandstringnoRun in a shell to save the SVG into the repository: the CLI decodes the link locally, fetches nothing, and embeds the source. Set --out to the path; add --theme dark for dark. Absent when too long.
nextstringyesThe next step in one sentence.

See also

DocWhy
API referenceEvery endpoint, and the error envelope
SchemasEvery request and response type
draw_from_patternThe same operation as an MCP tool
Tool referenceThe operations as callable tools