[{"data":1,"prerenderedAt":1134},["ShallowReactive",2],{"docs-nav":3,"cli-commands":171,"docs-\u002Fdocs\u002Fguides\u002Fdefining-and-promoting-operations":783,"docs-crumbs-\u002Fdocs\u002Fguides\u002Fdefining-and-promoting-operations":1130},[4],{"title":5,"path":6,"stem":7,"children":8},"Docs","\u002Fdocs","docs",[9,22,47,92,113,154,158],{"title":10,"path":11,"stem":12,"children":13},"Getting Started","\u002Fdocs\u002Fgetting-started","docs\u002F1.getting-started\u002Findex",[14,18],{"title":15,"path":16,"stem":17},"Installation","\u002Fdocs\u002Fgetting-started\u002Finstallation","docs\u002F1.getting-started\u002F1.installation",{"title":19,"path":20,"stem":21},"Quick start","\u002Fdocs\u002Fgetting-started\u002Fquick-start","docs\u002F1.getting-started\u002F2.quick-start",{"title":23,"path":24,"stem":25,"children":26},"Concepts","\u002Fdocs\u002Fconcepts","docs\u002F2.concepts\u002Findex",[27,31,35,39,43],{"title":28,"path":29,"stem":30},"Files-first","\u002Fdocs\u002Fconcepts\u002Ffiles-first","docs\u002F2.concepts\u002F1.files-first",{"title":32,"path":33,"stem":34},"The hierarchy","\u002Fdocs\u002Fconcepts\u002Fhierarchy","docs\u002F2.concepts\u002F2.hierarchy",{"title":36,"path":37,"stem":38},"OpenAPI as the source of truth","\u002Fdocs\u002Fconcepts\u002Fopenapi-source-of-truth","docs\u002F2.concepts\u002F3.openapi-source-of-truth",{"title":40,"path":41,"stem":42},"Instance visibility","\u002Fdocs\u002Fconcepts\u002Finstance-visibility","docs\u002F2.concepts\u002F4.instance-visibility",{"title":44,"path":45,"stem":46},"Environments","\u002Fdocs\u002Fconcepts\u002Fenvironments","docs\u002F2.concepts\u002F5.environments",{"title":48,"path":49,"stem":50,"children":51},"Guides","\u002Fdocs\u002Fguides","docs\u002F3.guides\u002Findex",[52,56,60,64,68,72,76,80,84,88],{"title":53,"path":54,"stem":55},"Importing a spec","\u002Fdocs\u002Fguides\u002Fimporting-a-spec","docs\u002F3.guides\u002F01.importing-a-spec",{"title":57,"path":58,"stem":59},"Migrating from Postman","\u002Fdocs\u002Fguides\u002Fmigrating-from-postman","docs\u002F3.guides\u002F02.migrating-from-postman",{"title":61,"path":62,"stem":63},"Importing HAR traffic","\u002Fdocs\u002Fguides\u002Fimporting-har-traffic","docs\u002F3.guides\u002F03.importing-har-traffic",{"title":65,"path":66,"stem":67},"Defining & promoting operations","\u002Fdocs\u002Fguides\u002Fdefining-and-promoting-operations","docs\u002F3.guides\u002F04.defining-and-promoting-operations",{"title":69,"path":70,"stem":71},"Request instances","\u002Fdocs\u002Fguides\u002Frequest-instances","docs\u002F3.guides\u002F05.request-instances",{"title":73,"path":74,"stem":75},"Auth & middlewares","\u002Fdocs\u002Fguides\u002Fauth-and-middlewares","docs\u002F3.guides\u002F06.auth-and-middlewares",{"title":77,"path":78,"stem":79},"Writing workflows","\u002Fdocs\u002Fguides\u002Fwriting-workflows","docs\u002F3.guides\u002F07.writing-workflows",{"title":81,"path":82,"stem":83},"CI\u002FCD","\u002Fdocs\u002Fguides\u002Fci-cd","docs\u002F3.guides\u002F08.ci-cd",{"title":85,"path":86,"stem":87},"Documenting an API","\u002Fdocs\u002Fguides\u002Fdocumenting-an-api","docs\u002F3.guides\u002F09.documenting-an-api",{"title":89,"path":90,"stem":91},"Pro license","\u002Fdocs\u002Fguides\u002Fpro-license","docs\u002F3.guides\u002F10.pro-license",{"title":93,"path":94,"stem":95,"children":96},"Interface","\u002Fdocs\u002Finterface","docs\u002F4.interface\u002Findex",[97,101,105,109],{"title":98,"path":99,"stem":100},"Navigation","\u002Fdocs\u002Finterface\u002Fnavigation","docs\u002F4.interface\u002F1.navigation",{"title":102,"path":103,"stem":104},"History","\u002Fdocs\u002Finterface\u002Fhistory","docs\u002F4.interface\u002F2.history",{"title":106,"path":107,"stem":108},"Command palette","\u002Fdocs\u002Finterface\u002Fcommand-palette","docs\u002F4.interface\u002F3.command-palette",{"title":110,"path":111,"stem":112},"Keyboard shortcuts","\u002Fdocs\u002Finterface\u002Fkeyboard-shortcuts","docs\u002F4.interface\u002F4.keyboard-shortcuts",{"title":114,"path":115,"stem":116,"children":117},"Reference","\u002Fdocs\u002Freference","docs\u002F5.reference\u002Findex",[118],{"title":119,"path":120,"stem":121,"children":122},"File formats","\u002Fdocs\u002Freference\u002Ffile-formats","docs\u002F5.reference\u002F1.file-formats\u002Findex",[123,127,131,135,138,142,146,150],{"title":124,"path":125,"stem":126},"config.json","\u002Fdocs\u002Freference\u002Ffile-formats\u002Fconfig-json","docs\u002F5.reference\u002F1.file-formats\u002F1.config-json",{"title":128,"path":129,"stem":130},"api.json","\u002Fdocs\u002Freference\u002Ffile-formats\u002Fapi-json","docs\u002F5.reference\u002F1.file-formats\u002F2.api-json",{"title":132,"path":133,"stem":134},"_resource.json","\u002Fdocs\u002Freference\u002Ffile-formats\u002Fresource-json","docs\u002F5.reference\u002F1.file-formats\u002F3.resource-json",{"title":69,"path":136,"stem":137},"\u002Fdocs\u002Freference\u002Ffile-formats\u002Frequest-instance","docs\u002F5.reference\u002F1.file-formats\u002F4.request-instance",{"title":139,"path":140,"stem":141},"Environment files","\u002Fdocs\u002Freference\u002Ffile-formats\u002Fenvironment-schema","docs\u002F5.reference\u002F1.file-formats\u002F5.environment-schema",{"title":143,"path":144,"stem":145},"schema.rules.json","\u002Fdocs\u002Freference\u002Ffile-formats\u002Fschema-rules","docs\u002F5.reference\u002F1.file-formats\u002F6.schema-rules",{"title":147,"path":148,"stem":149},"Documentation files","\u002Fdocs\u002Freference\u002Ffile-formats\u002Fdocumentation","docs\u002F5.reference\u002F1.file-formats\u002F7.documentation",{"title":151,"path":152,"stem":153},"Workflow files","\u002Fdocs\u002Freference\u002Ffile-formats\u002Fworkflow","docs\u002F5.reference\u002F1.file-formats\u002F8.workflow",{"title":155,"path":156,"stem":157},"CLI reference","\u002Fdocs\u002Fcli","docs\u002F6.cli\u002Findex",{"title":159,"path":160,"stem":161,"children":162},"Plugins","\u002Fdocs\u002Fplugins","docs\u002F7.plugins\u002Findex",[163,167],{"title":164,"path":165,"stem":166},"Using plugins","\u002Fdocs\u002Fplugins\u002Fusing-plugins","docs\u002F7.plugins\u002F1.using-plugins",{"title":168,"path":169,"stem":170},"Writing a plugin","\u002Fdocs\u002Fplugins\u002Fwriting-a-plugin","docs\u002F7.plugins\u002F2.writing-a-plugin",{"version":172,"namespaces":173},1,[174,207,293,429,499,529,617,653,734,761],{"namespace":175,"description":176,"commands":177},"project","Create and validate an API Craft project.",[178,189,195,201],{"name":179,"usage":180,"description":181,"flags":182,"examples":186,"updatedAt":188},"init","craftr project init \u003Cname> [--private]","Initialize an API Craft project in the current directory.",[183],{"name":184,"description":185},"--private","Mark the project as private (gitignore the apis directory and .api-craft).",[187],"craftr project init \"Petstore Project\"","2026-11-01T11:33:08Z",{"name":190,"usage":191,"description":192,"flags":193,"examples":194,"updatedAt":188},"validate","craftr project validate","Validate the project structure and report problems.",[],[],{"name":196,"usage":197,"description":198,"flags":199,"examples":200,"updatedAt":188},"trust","craftr project trust","Approve this project so its scripts (middlewares, custom auth, workflow scripts) can run. Persists until untrusted.",[],[197],{"name":202,"usage":203,"description":204,"flags":205,"examples":206,"updatedAt":188},"untrust","craftr project untrust","Refuse this project, blocking its scripts until it is trusted again.",[],[],{"namespace":208,"description":209,"commands":210},"api","Manage APIs and their default auth and overrides.",[211,217,230,237,248,262,279,286],{"name":212,"usage":213,"description":214,"flags":215,"examples":216,"updatedAt":188},"list","craftr api list","List the APIs in the project.",[],[],{"name":218,"usage":219,"description":220,"flags":221,"examples":227,"updatedAt":188},"create","craftr api create --api \u003Capi>","Create a new API.",[222],{"name":223,"short":224,"description":225,"required":226,"takesValue":226},"--api","-a","API slug.",true,[228,229],"craftr api create --api petstore-api","craftr api create -a petstore-api",{"name":231,"usage":232,"description":233,"flags":234,"examples":236,"updatedAt":188},"delete","craftr api delete --api \u003Capi>","Delete an API.",[235],{"name":223,"short":224,"description":225,"required":226,"takesValue":226},[],{"name":238,"usage":239,"description":240,"flags":241,"examples":246,"updatedAt":188},"set auth bearer","craftr api set auth bearer --token \u003Ctoken> [--api \u003Capi>]","Set the API default auth to a bearer token. Supports {{variables}}.",[242,245],{"name":243,"description":244,"required":226,"takesValue":226},"--token","Bearer token value. Supports {{variables}}.",{"name":223,"short":224,"description":225,"takesValue":226},[247],"craftr api set auth bearer --token \"{{apiKey}}\" --api petstore-api",{"name":249,"usage":250,"description":251,"flags":252,"examples":260,"updatedAt":188},"set auth basic","craftr api set auth basic --username \u003Cusername> --password \u003Cpassword> [--api \u003Capi>]","Set the API default auth to HTTP basic auth. Supports {{variables}}; the header is encoded once they are resolved.",[253,256,259],{"name":254,"description":255,"required":226,"takesValue":226},"--username","Username. Supports {{variables}}.",{"name":257,"description":258,"required":226,"takesValue":226},"--password","Password. Supports {{variables}}; prefer a secret variable.",{"name":223,"short":224,"description":225,"takesValue":226},[261],"craftr api set auth basic --username \"{{basicUsername}}\" --password \"{{basicPassword}}\" --api petstore-api",{"name":263,"usage":264,"description":265,"flags":266,"examples":277,"updatedAt":188},"set auth api-key","craftr api set auth api-key --in \u003Cheader|query> --name \u003Cname> --value \u003Cvalue> [--api \u003Capi>]","Set the API default auth to an API key sent as a header or query parameter.",[267,270,273,276],{"name":268,"description":269,"required":226,"takesValue":226},"--in","Where to send the key: header or query.",{"name":271,"description":272,"required":226,"takesValue":226},"--name","Header or query parameter name.",{"name":274,"description":275,"required":226,"takesValue":226},"--value","API key value. Supports {{variables}}.",{"name":223,"short":224,"description":225,"takesValue":226},[278],"craftr api set auth api-key --in header --name api_key --value \"{{apiKey}}\" -a petstore-api",{"name":280,"usage":281,"description":282,"flags":283,"examples":285,"updatedAt":188},"unset auth","craftr api unset auth [--api \u003Capi>]","Clear the API default auth.",[284],{"name":223,"short":224,"description":225,"takesValue":226},[],{"name":287,"usage":288,"description":289,"flags":290,"examples":292,"updatedAt":188},"overrides","craftr api overrides [--api \u003Capi>]","List all overrides for an API, grouped by kind (api, resource, operation, parameter).",[291],{"name":223,"short":224,"description":225,"takesValue":226},[],{"namespace":294,"description":295,"commands":296},"schema","Import an OpenAPI spec and manage the resource\u002Foperation mapping.",[297,316,323,330,337,344,351,358,368,376,383,390,406,413],{"name":298,"usage":299,"description":300,"flags":301,"examples":313,"updatedAt":188},"import","craftr schema import [source] [--api \u003Capi>] [--yes] [--no-persist-source] [--no-auto-clear-caught-up]","Import an OpenAPI spec: preview the diff, resolve conflicts, write, and remap. Source may be a file path or URL; omit to use the saved source or piped stdin.",[302,303,307,310],{"name":223,"short":224,"description":225,"takesValue":226},{"name":304,"short":305,"description":306},"--yes","-y","Skip the apply confirmation (required for non-interactive use).",{"name":308,"description":309},"--no-persist-source","Do not persist the spec source in api.json when a path or URL is given. Ignored for stdin and for a saved source.",{"name":311,"description":312},"--no-auto-clear-caught-up","Keep overrides whose value already matches the new source.",[314,315],"craftr schema import .\u002Fopenapi.json -a petstore-api","craftr schema import https:\u002F\u002Fpetstore3.swagger.io\u002Fapi\u002Fv3\u002Fopenapi.json -a petstore-api --yes",{"name":317,"usage":318,"description":319,"flags":320,"examples":322,"updatedAt":188},"diff","craftr schema diff [source] [--api \u003Capi>]","Preview the diff between the current schema and a candidate spec. Uses the persisted source if no path is given.",[321],{"name":223,"short":224,"description":225,"takesValue":226},[],{"name":324,"usage":325,"description":326,"flags":327,"examples":329,"updatedAt":188},"read","craftr schema read [--api \u003Capi>]","Read the effective schema (resources, unmapped, ignored, orphan rules).",[328],{"name":223,"short":224,"description":225,"takesValue":226},[],{"name":331,"usage":332,"description":333,"flags":334,"examples":336,"updatedAt":188},"unmapped","craftr schema unmapped [--api \u003Capi>]","List operations that are not mapped to any resource.",[335],{"name":223,"short":224,"description":225,"takesValue":226},[],{"name":338,"usage":339,"description":340,"flags":341,"examples":343,"updatedAt":188},"ignored","craftr schema ignored [--api \u003Capi>]","List ignored operations with their rule ids.",[342],{"name":223,"short":224,"description":225,"takesValue":226},[],{"name":345,"usage":346,"description":347,"flags":348,"examples":350,"updatedAt":188},"rename operation","craftr schema rename operation \u003Cresource> \u003Coperation-name> \u003Cnew-name> [--api \u003Capi>]","Rename a single operation within a resource.",[349],{"name":223,"short":224,"description":225,"takesValue":226},[],{"name":352,"usage":353,"description":354,"flags":355,"examples":357,"updatedAt":188},"rename resource","craftr schema rename resource \u003Cold-slug> \u003Cnew-slug> [--api \u003Capi>]","Rename a resource.",[356],{"name":223,"short":224,"description":225,"takesValue":226},[],{"name":359,"usage":360,"description":361,"flags":362,"examples":367,"updatedAt":188},"set-parent","craftr schema set-parent \u003Cresource> [parent] [--clear] [--api \u003Capi>]","Set or clear the parent of a resource. Provide a parent or pass --clear, not both.",[363,366],{"name":364,"description":365},"--clear","Clear the parent instead of setting it.",{"name":223,"short":224,"description":225,"takesValue":226},[],{"name":369,"usage":370,"description":371,"flags":372,"examples":374,"updatedAt":188},"map","craftr schema map \u003Coperation-id> \u003Cresource> \u003Coperation> [--api \u003Capi>]","Map an unmapped operation to a resource and operation name.",[373],{"name":223,"short":224,"description":225,"takesValue":226},[375],"craftr schema map updatePetWithForm Pet updateWithForm -a petstore-api",{"name":377,"usage":378,"description":379,"flags":380,"examples":382,"updatedAt":188},"ignore","craftr schema ignore \u003Coperation-id> [--api \u003Capi>]","Ignore an operation. It is removed from the effective schema.",[381],{"name":223,"short":224,"description":225,"takesValue":226},[],{"name":384,"usage":385,"description":386,"flags":387,"examples":389,"updatedAt":188},"unignore","craftr schema unignore \u003Coperation-id> [--api \u003Capi>]","Remove an ignore rule by operationId.",[388],{"name":223,"short":224,"description":225,"takesValue":226},[],{"name":391,"usage":392,"description":393,"flags":394,"examples":405,"updatedAt":188},"define","craftr schema define \u003Cresource> \u003Cname> --method \u003Cmethod> --path \u003Cpath> --operation-id \u003Cid> [--api \u003Capi>]","Define a local operation that does not exist in the source spec. Creates the resource if new.",[395,398,401,404],{"name":396,"description":397,"required":226,"takesValue":226},"--method","HTTP method (GET, POST, …).",{"name":399,"description":400,"required":226,"takesValue":226},"--path","OpenAPI path, e.g. \u002Fpet\u002F{petId}\u002Fvaccinations.",{"name":402,"description":403,"required":226,"takesValue":226},"--operation-id","Unique operationId.",{"name":223,"short":224,"description":225,"takesValue":226},[],{"name":407,"usage":408,"description":409,"flags":410,"examples":412,"updatedAt":188},"undefine","craftr schema undefine \u003Cresource> \u003Cname> [--api \u003Capi>]","Delete a locally-defined operation.",[411],{"name":223,"short":224,"description":225,"takesValue":226},[],{"name":414,"usage":415,"description":416,"flags":417,"examples":428,"updatedAt":188},"map-all","craftr schema map-all [--from \u003Cfile>] [--default] [--skip-all] [--api \u003Capi>]","Bulk-map every unmapped operation. Choose exactly one mode.",[418,421,424,427],{"name":419,"description":420,"takesValue":226},"--from","Path to a JSON array of {operationId, resource, operation, skip?}. Use \"-\" for stdin.",{"name":422,"description":423},"--default","Apply heuristic defaults to every unmapped operation.",{"name":425,"description":426},"--skip-all","Add an ignore rule for every unmapped operation.",{"name":223,"short":224,"description":225,"takesValue":226},[],{"namespace":298,"description":430,"commands":431},"Create an API from captured traffic or a collection.",[432,445,468,482],{"name":433,"usage":434,"description":435,"flags":436,"examples":442,"updatedAt":188},"har plan","craftr import har plan \u003Cfile.har> [--api \u003Cslug>] [--host \u003Chost>]","Preview what a HAR import would create: resources, operations, requests and the secret candidates that need a decision. Writes nothing.",[437,439],{"name":223,"short":224,"description":438,"takesValue":226},"Slug of the API to create (default: derived from the host).",{"name":440,"description":441,"takesValue":226},"--host","Keep only this host (default: the most frequent one).",[443,444],"craftr import har plan .\u002Ftraffic.har","craftr import har plan .\u002Ftraffic.har --host api.example.com --api petstore-traffic",{"name":446,"usage":447,"description":448,"flags":449,"examples":464,"updatedAt":188},"har apply","craftr import har apply \u003Cfile.har> [--api \u003Cslug>] [--host \u003Chost>] [--secret \u003Cin:name>…] [--drop \u003Cin:name>…] [--secret-all] [--drop-all]","Create a new API from a HAR file. Every secret candidate needs a decision: from the flags, or prompted in a terminal. Fails if the API already exists.",[450,451,452,455,458,461],{"name":223,"short":224,"description":438,"takesValue":226},{"name":440,"description":441,"takesValue":226},{"name":453,"description":454,"takesValue":226,"repeatable":226},"--secret","Store this candidate in local.secrets.env and reference it, e.g. header:authorization.",{"name":456,"description":457,"takesValue":226,"repeatable":226},"--drop","Leave this candidate out of the import, e.g. cookie:session.",{"name":459,"description":460},"--secret-all","Store every candidate as a secret.",{"name":462,"description":463},"--drop-all","Drop every candidate.",[465,466,467],"craftr import har apply .\u002Ftraffic.har","craftr import har apply .\u002Ftraffic.har --api petstore-traffic --secret header:authorization --drop cookie:session","craftr import har apply .\u002Ftraffic.har --api petstore-traffic --secret-all",{"name":469,"usage":470,"description":471,"flags":472,"examples":479,"updatedAt":188},"postman plan","craftr import postman plan \u003Ccollection.json> [--api \u003Cslug>] [--environment \u003Cenvironment.json>…]","Preview what a Postman import would create: resources, operations, requests, environments, middlewares, workflows, what cannot be converted, and the secret candidates that need a decision. Writes nothing.",[473,475],{"name":223,"short":224,"description":474,"takesValue":226},"Slug of the API to create (default: derived from the collection name).",{"name":476,"short":477,"description":478,"takesValue":226,"repeatable":226},"--environment","-e","Exported Postman environment to import as an environment of the new API.",[480,481],"craftr import postman plan .\u002Ftimers.postman_collection.json","craftr import postman plan .\u002Ftimers.postman_collection.json --environment .\u002Fstaging.postman_environment.json --api timers",{"name":483,"usage":484,"description":485,"flags":486,"examples":495,"updatedAt":188},"postman apply","craftr import postman apply \u003Ccollection.json> [--api \u003Cslug>] [--environment \u003Cenvironment.json>…] [--secret \u003Cin:name>…] [--drop \u003Cin:name>…] [--secret-all] [--drop-all]","Create a new API from a Postman collection. Every secret candidate needs a decision: from the flags, or prompted in a terminal. Scripts are written commented out under a throw, so they fail until rewritten. Fails if the API already exists.",[487,488,489,491,493,494],{"name":223,"short":224,"description":474,"takesValue":226},{"name":476,"short":477,"description":478,"takesValue":226,"repeatable":226},{"name":453,"description":490,"takesValue":226,"repeatable":226},"Store this candidate in the git-ignored .secrets.env files and reference it, e.g. variable:access_token.",{"name":456,"description":492,"takesValue":226,"repeatable":226},"Drop the value of this candidate (a variable stays declared, a header is left out), e.g. auth:apikey.",{"name":459,"description":460},{"name":462,"description":463},[496,497,498],"craftr import postman apply .\u002Ftimers.postman_collection.json --environment .\u002Fstaging.postman_environment.json","craftr import postman apply .\u002Ftimers.postman_collection.json --secret variable:access_token --drop auth:apikey","craftr import postman apply .\u002Ftimers.postman_collection.json --api timers --secret-all",{"namespace":500,"description":501,"commands":502},"spec","Read the OpenAPI spec, or promote defined operations into it.",[503,513],{"name":324,"usage":504,"description":505,"flags":506,"examples":511,"updatedAt":188},"craftr spec read [--api \u003Capi>] [--imported]","Print the effective OpenAPI spec, or the raw imported spec with --imported.",[507,508],{"name":223,"short":224,"description":225,"takesValue":226},{"name":509,"description":510},"--imported","Print the raw imported spec (spec.imported.json) instead of the projected one.",[512],"craftr spec read -a petstore-api | jq '.paths | keys'",{"name":514,"usage":515,"description":516,"flags":517,"examples":525,"updatedAt":188},"promote","craftr spec promote [--api \u003Capi>] [--resource \u003Cresource>] [--operation \u003Cresource\u002Foperation>]","Write defined operations, with their parameters, request body and responses, into the API spec (spec.imported.json). The API then owns its spec: an upstream file or URL source is detached.",[518,519,522],{"name":223,"short":224,"description":225,"takesValue":226},{"name":520,"description":521,"takesValue":226},"--resource","Only promote the defined operations of this resource.",{"name":523,"description":524,"takesValue":226},"--operation","Only promote this defined operation.",[526,527,528],"craftr spec promote -a timers","craftr spec promote -a timers --resource Timers","craftr spec promote -a timers --operation Timers\u002Fcreate",{"namespace":530,"description":531,"commands":532},"req","List, run, and manage request instances.",[533,546,553,560,570],{"name":212,"usage":534,"description":535,"flags":536,"examples":545,"updatedAt":188},"craftr req list [--resource \u003Cresource>] [--filter \u003Ctext>] [--api \u003Capi>]","List request instances, optionally filtered.",[537,540,544],{"name":520,"short":538,"description":539,"takesValue":226},"-r","Resource slug to list. Omit to list every request.",{"name":541,"short":542,"description":543,"takesValue":226},"--filter","-f","Case-insensitive substring matched against resource and request name.",{"name":223,"short":224,"description":225,"takesValue":226},[],{"name":547,"usage":548,"description":549,"flags":550,"examples":552,"updatedAt":188},"rename","craftr req rename \u003Cresource\u002Fname> \u003Cnew-name> [--api \u003Capi>]","Rename a request instance.",[551],{"name":223,"short":224,"description":225,"takesValue":226},[],{"name":554,"usage":555,"description":556,"flags":557,"examples":559,"updatedAt":188},"duplicate","craftr req duplicate \u003Cresource\u002Fname> \u003Cnew-name> [--api \u003Capi>]","Duplicate a request instance. The copy is created as private.",[558],{"name":223,"short":224,"description":225,"takesValue":226},[],{"name":561,"usage":562,"description":563,"flags":564,"examples":569,"updatedAt":188},"set-visibility","craftr req set-visibility \u003Cresource\u002Fname> \u003Cpublic|private> [--api \u003Capi>] [--new-name \u003Cname>]","Change a request instance's visibility (public or private).",[565,566],{"name":223,"short":224,"description":225,"takesValue":226},{"name":567,"description":568,"takesValue":226},"--new-name","Rename the request as it changes visibility.",[],{"name":571,"usage":572,"description":573,"flags":574,"examples":610,"updatedAt":188},"run","craftr req run \u003Cresource\u002Fname> --env \u003Cenv> [--api \u003Capi>] [--var \u003Ckey=value>…] [--set \u003Cscope.key=value>…] [--enable-middleware \u003Cref>…] [--disable-middleware \u003Cref>…] [--trust] [--from-history] [--max-age \u003Cduration>] [--or-run] [--full] [--verbose \u003Clevel>]","Execute a request instance against an environment. Prints the response body by default.",[575,576,579,582,585,588,591,594,597,600,603,606],{"name":223,"short":224,"description":225,"takesValue":226},{"name":577,"short":477,"description":578,"required":226,"takesValue":226},"--env","Environment name.",{"name":580,"description":581,"takesValue":226,"repeatable":226},"--var","Override an environment variable: key=value. The variable must be declared in the environment schema.",{"name":583,"description":584,"takesValue":226,"repeatable":226},"--set","Override a request parameter: \u003Cpath|query|header|cookie|body|middleware>.key=value. Body keys support dot-notation. middleware.\u003Cname[#export]>.\u003Ckey>=\u003Cvalue> overrides a middleware option for this run and enables that middleware.",{"name":586,"description":587,"takesValue":226,"repeatable":226},"--enable-middleware","Enable a middleware of the request chain for this run only: \"name\" (every export of that file) or \"name#export\". Not saved.",{"name":589,"description":590,"takesValue":226,"repeatable":226},"--disable-middleware","Disable a middleware of the request chain for this run only: \"name\" or \"name#export\". Not saved.",{"name":592,"description":593},"--trust","Allow this project's scripts to run for this invocation only. Never saved.",{"name":595,"description":596},"--from-history","Don't send the request: re-run after-response middlewares on the latest stored response for this request and environment. Writes no history entry.",{"name":598,"description":599,"takesValue":226},"--max-age","With --from-history: only use a stored response younger than this (30s, 10m, 2h, 1d).",{"name":601,"description":602},"--or-run","With --from-history: send the request when no usable stored response exists.",{"name":604,"description":605},"--full","Print the full execution result instead of just the response body.",{"name":607,"short":608,"description":609,"takesValue":226},"--verbose","-v","Print the trace to stderr. -v is info, -vv adds debug.",[611,612,613,614,615,616],"craftr req run Pet\u002Fget-pet -e dev","craftr req run Pet\u002Fget-pet -e dev --set path.petId=3 | jq '.name'","craftr req run Pet\u002Fget-pet -e dev --var apiKey=sk-test --full","craftr req run Pet\u002Fget-pet -e dev --disable-middleware tracing --set middleware.filters#byStatus.status=404","craftr req run Pet\u002Fget-pet -e dev --from-history | jq '.name'","craftr req run Pet\u002Fget-pet -e dev --from-history --max-age 10m --or-run",{"namespace":618,"description":619,"commands":620},"env","Manage environments and their values.",[621,627,633,641,647],{"name":212,"usage":622,"description":623,"flags":624,"examples":626,"updatedAt":188},"craftr env list [--api \u003Capi>]","List environments.",[625],{"name":223,"short":224,"description":225,"takesValue":226},[],{"name":324,"usage":628,"description":629,"flags":630,"examples":632,"updatedAt":188},"craftr env read \u003Cenv> [--api \u003Capi>]","Read an environment's values, with the extends chain resolved.",[631],{"name":223,"short":224,"description":225,"takesValue":226},[],{"name":634,"usage":635,"description":636,"flags":637,"examples":639,"updatedAt":188},"write","craftr env write \u003Cenv> \u003Ckey> \u003Cvalue> [--api \u003Capi>]","Write a single environment variable. The value is JSON-parsed if it is a valid scalar, otherwise stored as a string.",[638],{"name":223,"short":224,"description":225,"takesValue":226},[640],"craftr env write dev baseUrl https:\u002F\u002Fpetstore3.swagger.io\u002Fapi\u002Fv3",{"name":231,"usage":642,"description":643,"flags":644,"examples":646,"updatedAt":188},"craftr env delete \u003Cenv> [--api \u003Capi>]","Delete an environment.",[645],{"name":223,"short":224,"description":225,"takesValue":226},[],{"name":547,"usage":648,"description":649,"flags":650,"examples":652,"updatedAt":188},"craftr env rename \u003Cold-name> \u003Cnew-name> [--api \u003Capi>]","Rename an environment.",[651],{"name":223,"short":224,"description":225,"takesValue":226},[],{"namespace":654,"description":655,"commands":656},"workflow","Run project-scoped workflows.",[657,662,690,697,708,713,718,729],{"name":212,"usage":658,"description":659,"flags":660,"examples":661,"updatedAt":188},"craftr workflow list","List every workflow in the project.",[],[658],{"name":571,"usage":663,"description":664,"flags":665,"examples":686,"updatedAt":188},"craftr workflow run [workflow…] [--all] [--trust] [--env \u003Capi=env>…] [--input \u003Ckey=value>…] [--concurrency \u003Cn>] [--on-failure \u003Chalt|continue>] [--full-output \u003Cfile>] [--verbose \u003Clevel>]","Run one or more workflows (or every workflow with --all) and aggregate the results. Prints a JSON summary report on stdout, a human summary on stderr, and exits 1 if any workflow failed (130 if cancelled).",[666,669,670,672,675,678,681,684],{"name":667,"description":668},"--all","Run every workflow in the project. Mutually exclusive with named workflows.",{"name":592,"description":593},{"name":577,"short":477,"description":671,"takesValue":226,"repeatable":226},"Bind an environment to an API: \u003Capi>=\u003Cenv>. Repeat once per API the run touches (the union across a batch).",{"name":673,"description":674,"takesValue":226,"repeatable":226},"--input","Workflow input: [\u003Cworkflow>:]\u003Ckey>=\u003Cvalue>. Without a workflow prefix it applies to every workflow in the batch.",{"name":676,"description":677,"takesValue":226},"--concurrency","Workflows in flight at once (default 4). 1 runs them sequentially.",{"name":679,"description":680,"takesValue":226},"--on-failure","halt stops starting new workflows after a failure; continue (default) runs them all. Separate from a workflow file's own onFailure, which governs blocks within a run.",{"name":682,"description":683,"takesValue":226},"--full-output","Write the complete run result (every block and response) to this file. Omitted, that detail is discarded.",{"name":607,"short":608,"description":685,"takesValue":226},"Progress and traces to stderr: -v workflow level, -vv block logs, -vvv debug.",[687,688,689],"craftr workflow run pet-lifecycle --env petstore-api=prod","craftr workflow run publish-and-verify -e petstore-api=prod -e catalog=staging","craftr workflow run --all -e petstore-api=prod -e catalog=staging",{"name":190,"usage":691,"description":692,"flags":693,"examples":694,"updatedAt":188},"craftr workflow validate [workflow…]","Check that a workflow's references resolve (api, resource, operation, instance, scripts) and refresh the generated script typings. Omit the name to check every workflow. Sends no request, so it is cheap to run in CI before a run.",[],[695,696],"craftr workflow validate","craftr workflow validate pet-lifecycle",{"name":698,"usage":699,"description":700,"flags":701,"examples":705,"updatedAt":188},"history","craftr workflow history [run-id] [--limit \u003Cn>]","List past workflow runs newest first, or read one run in full by id. Run ids are the ISO timestamp of the run with \":\" replaced by \"-\".",[702],{"name":703,"description":704,"takesValue":226},"--limit","Keep only the first N summaries. Ignored when an id is given.",[706,707],"craftr workflow history --limit 5","craftr workflow history 2026-08-23T10-14-02.981Z",{"name":547,"usage":709,"description":710,"flags":711,"examples":712,"updatedAt":188},"craftr workflow rename \u003Cold-name> \u003Cnew-name>","Rename a workflow, its scripts directory included.",[],[],{"name":554,"usage":714,"description":715,"flags":716,"examples":717,"updatedAt":188},"craftr workflow duplicate \u003Csource-name> \u003Cnew-name>","Duplicate a workflow, its scripts directory included.",[],[],{"name":719,"usage":720,"description":721,"flags":722,"examples":726,"updatedAt":188},"move-block","craftr workflow move-block \u003Cworkflow> \u003Cblock> \u003Cworkflow> [--index \u003Cn>]","Move a block, with its children and scripts, to another workflow. Clashing block ids get a numeric suffix; references that now cross workflows are listed in brokenReferences.",[723],{"name":724,"description":725,"takesValue":226},"--index","Position in the target top-level list (default: end).",[727,728],"craftr workflow move-block pet-lifecycle check-status smoke","craftr workflow move-block pet-lifecycle check-status smoke --index 0",{"name":231,"usage":730,"description":731,"flags":732,"examples":733,"updatedAt":188},"craftr workflow delete \u003Cworkflow-name>","Delete a workflow and its scripts directory.",[],[],{"namespace":735,"description":736,"commands":737},"license","Install, inspect or remove the Pro license. Per user, not per project, so these work from any directory.",[738,744,755],{"name":739,"usage":740,"description":741,"flags":742,"examples":743,"updatedAt":188},"get","craftr license get","Print the active license state as JSON: status, tier, who it is issued to, expiry, features and limits. A limit of -1 means unlimited.",[],[740],{"name":745,"usage":746,"description":747,"flags":748,"examples":752,"updatedAt":188},"install","craftr license install [--file \u003Cpath>]","Install a license from a file or from stdin. Verifies the signature first; on failure the current license, if any, is left in place.",[749],{"name":750,"description":751,"takesValue":226},"--file","Path to the license file. Reads stdin when omitted.",[753,754],"craftr license install --file=license.key","cat license.key | craftr license install",{"name":756,"usage":757,"description":758,"flags":759,"examples":760,"updatedAt":188},"remove","craftr license remove","Delete the installed license and fall back to the Free plan. Prints the resulting state.",[],[757],{"namespace":762,"description":763,"commands":764},"completion","Shell tab-completion management.",[765,775],{"name":745,"usage":766,"description":767,"flags":768,"examples":772,"updatedAt":188},"craftr completion install [--shell \u003Cbash|zsh|fish>]","Install shell tab-completion. Writes the completion script and, for bash and zsh, adds a marked block to the shell rc file that sources it.",[769],{"name":770,"description":771,"takesValue":226},"--shell","bash, zsh or fish. Defaults to the shell named by $SHELL.",[773,774],"craftr completion install","craftr completion install --shell fish",{"name":776,"usage":777,"description":778,"flags":779,"examples":781,"updatedAt":188},"uninstall","craftr completion uninstall [--shell \u003Cbash|zsh|fish>]","Remove the completion script and the block it added to the shell rc file.",[780],{"name":770,"description":771,"takesValue":226},[782],"craftr completion uninstall",{"id":784,"title":65,"body":785,"description":1123,"extension":1124,"lastmod":1125,"meta":1126,"navigation":1127,"path":66,"seo":1128,"stem":67,"__hash__":1129},"docs\u002Fdocs\u002F3.guides\u002F04.defining-and-promoting-operations.md",{"type":786,"value":787,"toc":1115},"minimark",[788,792,810,815,822,896,902,906,913,960,967,972,979,983,990,993,1050,1061,1069,1074,1088,1101,1104,1108,1111],[789,790,65],"h1",{"id":791},"defining-promoting-operations",[793,794,795,796,800,801,805,806,809],"p",{},"Most operations come from an imported OpenAPI spec. A ",[797,798,799],"strong",{},"defined"," operation is one you add yourself,\nby hand or through a ",[802,803,804],"a",{"href":58},"Postman"," or\n",[802,807,808],{"href":62},"HAR"," import: it exists in your project, not in the spec.\nPromotion is how a defined operation becomes part of the spec.",[811,812,814],"h2",{"id":813},"defining-an-operation","Defining an operation",[793,816,817,818,821],{},"In the schema sidebar, use ",[797,819,820],{},"+"," on a resource (or the API) and give the method, path and\noperationId. From the CLI:",[823,824,829],"pre",{"className":825,"code":826,"language":827,"meta":828,"style":828},"language-bash shiki shiki-themes github-light github-dark","craftr schema define Pet adopt --method POST --path \u002Fpet\u002F{petId}\u002Fadopt --operation-id adoptPet -a petstore-api\ncraftr schema undefine Pet adopt -a petstore-api\n","bash","",[830,831,832,878],"code",{"__ignoreMap":828},[833,834,836,840,844,847,850,853,857,860,863,866,869,872,875],"span",{"class":835,"line":172},"line",[833,837,839],{"class":838},"sScJk","craftr",[833,841,843],{"class":842},"sZZnC"," schema",[833,845,846],{"class":842}," define",[833,848,849],{"class":842}," Pet",[833,851,852],{"class":842}," adopt",[833,854,856],{"class":855},"sj4cs"," --method",[833,858,859],{"class":842}," POST",[833,861,862],{"class":855}," --path",[833,864,865],{"class":842}," \u002Fpet\u002F{petId}\u002Fadopt",[833,867,868],{"class":855}," --operation-id",[833,870,871],{"class":842}," adoptPet",[833,873,874],{"class":855}," -a",[833,876,877],{"class":842}," petstore-api\n",[833,879,881,883,885,888,890,892,894],{"class":835,"line":880},2,[833,882,839],{"class":838},[833,884,843],{"class":842},[833,886,887],{"class":842}," undefine",[833,889,849],{"class":842},[833,891,852],{"class":842},[833,893,874],{"class":855},[833,895,877],{"class":842},[793,897,898,899,901],{},"A defined operation is marked ",[797,900,799],{}," in the sidebar. Its method, path and operationId are\neditable in the operation header.",[811,903,905],{"id":904},"editing-its-contract","Editing its contract",[793,907,908,909,912],{},"For a defined operation, the ",[797,910,911],{},"Definition"," tab is an editor: the contract you see is the whole\ncontract, there is no spec underneath.",[914,915,916,922,936,942],"ul",{},[917,918,919],"li",{},[797,920,921],{},"Summary and description.",[917,923,924,927,928,931,932,935],{},[797,925,926],{},"Parameters",": name, location (path, query, header, cookie), type, required and description.\nPath parameters are always required; a ",[830,929,930],{},"{placeholder}"," in the path without a parameter is\nflagged with a one-click ",[797,933,934],{},"Add it",".",[917,937,938,941],{},[797,939,940],{},"Request body",": add or remove it, its content type, whether it's required, and its JSON schema.",[917,943,944,947,948,951,952,955,956,959],{},[797,945,946],{},"Responses",": add or remove status codes (",[830,949,950],{},"100","–",[830,953,954],{},"599"," or ",[830,957,958],{},"default","), their description and body\nschema.",[793,961,962,963,966],{},"Schemas are edited as JSON in the right-hand pane; invalid JSON is shown and not saved. Switch the\npane to ",[797,964,965],{},"Preview"," for the usual example and schema tree. Every change can be undone.",[968,969],"screenshot",{"alt":970,"src":971},"The Definition tab of a defined operation, with editable parameters and the JSON schema editor","\u002Fimages\u002Fguides\u002Fdefined-operation-contract.png",[793,973,974,975,978],{},"Operations that come from the spec keep the read-only Definition tab and the ",[797,976,977],{},"Customize"," section:\nyour edits there are overrides on top of the spec, which re-imports keep track of.",[811,980,982],{"id":981},"promoting-to-the-spec","Promoting to the spec",[793,984,985,986,989],{},"Once the contract is right, promote it. The operation, with its parameters, request body and\nresponses, is written into ",[830,987,988],{},"spec.imported.json"," and becomes a regular spec operation: same resource,\nsame name, same requests and workflows.",[793,991,992],{},"Promote one operation, a resource, or everything defined in the API:",[823,994,996],{"className":825,"code":995,"language":827,"meta":828,"style":828},"craftr spec promote -a petstore-api --operation Pet\u002Fadopt\ncraftr spec promote -a petstore-api --resource Pet\ncraftr spec promote -a petstore-api\n",[830,997,998,1019,1037],{"__ignoreMap":828},[833,999,1000,1002,1005,1008,1010,1013,1016],{"class":835,"line":172},[833,1001,839],{"class":838},[833,1003,1004],{"class":842}," spec",[833,1006,1007],{"class":842}," promote",[833,1009,874],{"class":855},[833,1011,1012],{"class":842}," petstore-api",[833,1014,1015],{"class":855}," --operation",[833,1017,1018],{"class":842}," Pet\u002Fadopt\n",[833,1020,1021,1023,1025,1027,1029,1031,1034],{"class":835,"line":880},[833,1022,839],{"class":838},[833,1024,1004],{"class":842},[833,1026,1007],{"class":842},[833,1028,874],{"class":855},[833,1030,1012],{"class":842},[833,1032,1033],{"class":855}," --resource",[833,1035,1036],{"class":842}," Pet\n",[833,1038,1040,1042,1044,1046,1048],{"class":835,"line":1039},3,[833,1041,839],{"class":838},[833,1043,1004],{"class":842},[833,1045,1007],{"class":842},[833,1047,874],{"class":855},[833,1049,877],{"class":842},[793,1051,1052,1053,1056,1057,1060],{},"In the app: ",[797,1054,1055],{},"Promote to spec"," in a defined operation's header or menu, ",[797,1058,1059],{},"Promote defined\noperations to spec"," in a resource's menu, or the button in the API header. Each asks for\nconfirmation, and the whole promotion is a single undo step.",[793,1062,1063,1064,1066,1067,935],{},"The promoted operation is completed with what OpenAPI requires and a defined operation may lack: a\n",[830,1065,958],{}," response when there is none, and a required path parameter for each ",[830,1068,930],{},[1070,1071,1073],"h3",{"id":1072},"the-api-now-owns-its-spec","The API now owns its spec",[793,1075,1076,1077,1079,1080,1083,1084,1087],{},"After a promotion, ",[830,1078,128],{}," carries ",[830,1081,1082],{},"\"specSource\": { \"type\": \"self\" }",": API Craft is the author\nof this spec, there is nothing upstream to re-import. An API with no ",[830,1085,1086],{},"specSource"," at all means the\nsame thing.",[1089,1090,1091],"warning",{},[793,1092,1093,1096,1097,1100],{},[797,1094,1095],{},"Promoting detaches an upstream source."," If the API re-imports from a file or URL, promotion\nreplaces that source with ",[830,1098,1099],{},"self",", and the next import would no longer find the promoted operations\nupstream. The app shows this in the confirmation and the CLI prints a warning. To import from a file\nor URL again later, pass it explicitly: it becomes the source again.",[793,1102,1103],{},"Only defined operations are promoted. Overrides you made on operations that came from the spec\nstay overrides, so you can still tell your local changes from the imported contract.",[811,1105,1107],{"id":1106},"why-promotion-is-explicit","Why promotion is explicit",[793,1109,1110],{},"An imported contract is inferred from samples, and its resource names are a best guess. Writing it\nstraight into the spec would make it authoritative before anyone reviewed it. So an import only\ncreates defined operations; you correct them, then promote when you're satisfied.",[1112,1113,1114],"style",{},"html pre.shiki code .sScJk, html code.shiki .sScJk{--shiki-default:#6F42C1;--shiki-dark:#B392F0}html pre.shiki code .sZZnC, html code.shiki .sZZnC{--shiki-default:#032F62;--shiki-dark:#9ECBFF}html pre.shiki code .sj4cs, html code.shiki .sj4cs{--shiki-default:#005CC5;--shiki-dark:#79B8FF}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}",{"title":828,"searchDepth":880,"depth":880,"links":1116},[1117,1118,1119,1122],{"id":813,"depth":880,"text":814},{"id":904,"depth":880,"text":905},{"id":981,"depth":880,"text":982,"children":1120},[1121],{"id":1072,"depth":1039,"text":1073},{"id":1106,"depth":880,"text":1107},"Model operations without a spec, edit their contract, and promote them into a real OpenAPI spec the API then owns.","md","2026-10-25T21:36:21+01:00",{},null,{"title":65,"description":1123},"hUtDzORDSPwV0iZGlca46tCoRJV0Tze1PuAjb-s3nQE",[1131,1132],{"path":49,"title":48},{"path":6,"title":1133},"Documentation",1793542849756]