[{"data":1,"prerenderedAt":1950},["ShallowReactive",2],{"docs-nav":3,"cli-commands":171,"docs-\u002Fdocs\u002Fguides\u002Fmigrating-from-postman":783,"docs-crumbs-\u002Fdocs\u002Fguides\u002Fmigrating-from-postman":1946},[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":57,"body":785,"description":1939,"extension":1940,"lastmod":1941,"meta":1942,"navigation":1943,"path":58,"seo":1944,"stem":59,"__hash__":1945},"docs\u002Fdocs\u002F3.guides\u002F02.migrating-from-postman.md",{"type":786,"value":787,"toc":1929},"minimark",[788,792,801,804,829,841,846,871,875,878,931,934,1045,1060,1065,1069,1075,1105,1178,1181,1201,1272,1275,1294,1298,1480,1485,1495,1624,1635,1638,1644,1732,1736,1920,1925],[789,790,57],"h1",{"id":791},"migrating-from-postman",[793,794,795,796,800],"p",{},"An import is a one-off: it reads a Postman collection (and, optionally, its environment files),\nwrites plain API Craft files into a ",[797,798,799],"strong",{},"new API",", and steps aside. There is no live link to Postman,\nno re-import and no sync. What it writes is ordinary project content you edit with the normal\ntools.",[793,802,803],{},"What it does for you:",[805,806,807,816,819,826],"ul",{},[808,809,810,811,815],"li",{},"every request becomes a ",[812,813,814],"a",{"href":70},"request instance",", grouped into\nresources and operations by the same mapper an OpenAPI import uses;",[808,817,818],{},"each operation gets a contract (parameters, request body, responses) inferred from your\nrequests and their saved examples;",[808,820,821,822,825],{},"collection variables and environments become API Craft\n",[812,823,824],{"href":45},"environments",", with secrets kept out of committed files;",[808,827,828],{},"bearer, API key and basic auth carry over as-is.",[793,830,831,832,835,836,840],{},"What it deliberately does ",[797,833,834],{},"not"," do is translate JavaScript. Postman scripts are copied into\nyour project commented out, under a ",[837,838,839],"code",{},"throw",", so nothing passes by accident before you rewrite it.",[842,843,845],"h2",{"id":844},"_1-export-from-postman","1. Export from Postman",[805,847,848,862],{},[808,849,850,853,854,857,858,861],{},[797,851,852],{},"Collection",": on the collection, ",[797,855,856],{},"⋯ → Export",", format ",[797,859,860],{},"Collection v2.1"," (v2.0 works too;\nv1 is refused).",[808,863,864,866,867,870],{},[797,865,44],{},": ",[797,868,869],{},"Environments → ⋯ → Export",", one file per environment you want to keep.",[842,872,874],{"id":873},"_2-preview-the-import","2. Preview the import",[793,876,877],{},"Nothing is written until you apply. Start with the plan:",[879,880,885],"pre",{"className":881,"code":882,"language":883,"meta":884,"style":884},"language-bash shiki shiki-themes github-light github-dark","craftr import postman plan .\u002Fpetstore.postman_collection.json \\\n  --environment .\u002Fdev.postman_environment.json \\\n  --environment .\u002Fprod.postman_environment.json\n","bash","",[837,886,887,912,923],{"__ignoreMap":884},[888,889,891,895,899,902,905,908],"span",{"class":890,"line":172},"line",[888,892,894],{"class":893},"sScJk","craftr",[888,896,898],{"class":897},"sZZnC"," import",[888,900,901],{"class":897}," postman",[888,903,904],{"class":897}," plan",[888,906,907],{"class":897}," .\u002Fpetstore.postman_collection.json",[888,909,911],{"class":910},"sj4cs"," \\\n",[888,913,915,918,921],{"class":890,"line":914},2,[888,916,917],{"class":910},"  --environment",[888,919,920],{"class":897}," .\u002Fdev.postman_environment.json",[888,922,911],{"class":910},[888,924,926,928],{"class":890,"line":925},3,[888,927,917],{"class":910},[888,929,930],{"class":897}," .\u002Fprod.postman_environment.json\n",[793,932,933],{},"The plan is JSON. The parts worth reading:",[935,936,937,950],"table",{},[938,939,940],"thead",{},[941,942,943,947],"tr",{},[944,945,946],"th",{},"Key",[944,948,949],{},"What it tells you",[951,952,953,966,976,986,996,1006,1020,1030],"tbody",{},[941,954,955,960],{},[956,957,958],"td",{},[837,959,208],{},[956,961,962,963,965],{},"The slug (derived from the collection name; ",[837,964,223],{}," picks another) and the base URL.",[941,967,968,973],{},[956,969,970],{},[837,971,972],{},"resources",[956,974,975],{},"How requests were grouped into resources and operations, with method and path.",[941,977,978,983],{},[956,979,980],{},[837,981,982],{},"instances",[956,984,985],{},"One per Postman request, with its name and concrete URL.",[941,987,988,993],{},[956,989,990],{},[837,991,992],{},"secrets",[956,994,995],{},"The candidates you must decide before applying (see below).",[941,997,998,1003],{},[956,999,1000],{},[837,1001,1002],{},"postman.environments",[956,1004,1005],{},"The environments that will be created, their level and variables.",[941,1007,1008,1017],{},[956,1009,1010,1013,1014],{},[837,1011,1012],{},"postman.middlewares"," \u002F ",[837,1015,1016],{},"postman.workflows",[956,1018,1019],{},"Where your pre-request and test scripts will land.",[941,1021,1022,1027],{},[956,1023,1024],{},[837,1025,1026],{},"postman.standalone",[956,1028,1029],{},"Requests on another host, kept as standalone instances.",[941,1031,1032,1037],{},[956,1033,1034],{},[837,1035,1036],{},"postman.unconverted",[956,1038,1039,1040,1044],{},"Everything that could not be translated (see ",[812,1041,1043],{"href":1042},"#what-isnt-converted","What isn't converted",").",[793,1046,1047,1048,1051,1052,1055,1056,1059],{},"In the app, open the ",[797,1049,1050],{},"New API"," wizard and pick ",[797,1053,1054],{},"Import a Postman collection"," under the name\nfield. Choose the collection and its environment files, then ",[797,1057,1058],{},"Analyze",": the wizard shows the\nsame plan and the secret decisions on one screen.",[1061,1062],"screenshot",{"alt":1063,"src":1064},"The Postman import step of the New API wizard with the summary and the secret decisions","\u002Fimages\u002Fguides\u002Fpostman-import-wizard.png",[842,1066,1068],{"id":1067},"_3-decide-every-secret","3. Decide every secret",[793,1070,1071,1072,1074],{},"Postman doesn't really separate values from secrets, so the import proposes candidates and you\ndecide each one. Nothing is written until every candidate has a decision; there is no ",[837,1073,304],{},".",[793,1076,1077,1078,1081,1082,1081,1085,1081,1088,1091,1092,1081,1095,1081,1098,1101,1102,1104],{},"A value is a candidate when its name looks like a credential (",[837,1079,1080],{},"token",", ",[837,1083,1084],{},"key",[837,1086,1087],{},"secret",[837,1089,1090],{},"password",",\n",[837,1093,1094],{},"auth",[837,1096,1097],{},"session",[837,1099,1100],{},"credential","…) or Postman marked it ",[837,1103,1087],{},". Candidates come in three kinds:",[935,1106,1107,1119],{},[938,1108,1109],{},[941,1110,1111,1113,1116],{},[944,1112,946],{},[944,1114,1115],{},"Example",[944,1117,1118],{},"What it is",[951,1120,1121,1136,1157],{},[941,1122,1123,1128,1133],{},[956,1124,1125],{},[837,1126,1127],{},"variable:\u003Cname>",[956,1129,1130],{},[837,1131,1132],{},"variable:access_token",[956,1134,1135],{},"A collection or environment variable.",[941,1137,1138,1143,1154],{},[956,1139,1140],{},[837,1141,1142],{},"auth:\u003Ctype>",[956,1144,1145,1081,1148,1081,1151],{},[837,1146,1147],{},"auth:bearer",[837,1149,1150],{},"auth:basic",[837,1152,1153],{},"auth:apikey",[956,1155,1156],{},"A credential typed directly into an auth tab instead of a variable.",[941,1158,1159,1170,1175],{},[956,1160,1161,1013,1164,1013,1167],{},[837,1162,1163],{},"header:",[837,1165,1166],{},"query:",[837,1168,1169],{},"cookie:",[956,1171,1172],{},[837,1173,1174],{},"header:x-api-key",[956,1176,1177],{},"A literal credential in a request parameter.",[793,1179,1180],{},"Two decisions:",[805,1182,1183,1195],{},[808,1184,1185,1187,1188,1191,1192,1074],{},[797,1186,1087],{},": the value goes to the gitignored ",[837,1189,1190],{},"\u003Cenvironment>.secrets.env"," and requests reference\nit as ",[837,1193,1194],{},"{{variable}}",[808,1196,1197,1200],{},[797,1198,1199],{},"drop",": the value is not imported. A variable stays declared (secret, without value) so you\nfill it later; a literal header or query parameter is left out of the request.",[879,1202,1204],{"className":881,"code":1203,"language":883,"meta":884,"style":884},"craftr import postman apply .\u002Fpetstore.postman_collection.json \\\n  --environment .\u002Fdev.postman_environment.json \\\n  --secret variable:access_token --drop auth:apikey\n\n# or decide everything the same way\ncraftr import postman apply .\u002Fpetstore.postman_collection.json --secret-all\n",[837,1205,1206,1221,1229,1243,1249,1256],{"__ignoreMap":884},[888,1207,1208,1210,1212,1214,1217,1219],{"class":890,"line":172},[888,1209,894],{"class":893},[888,1211,898],{"class":897},[888,1213,901],{"class":897},[888,1215,1216],{"class":897}," apply",[888,1218,907],{"class":897},[888,1220,911],{"class":910},[888,1222,1223,1225,1227],{"class":890,"line":914},[888,1224,917],{"class":910},[888,1226,920],{"class":897},[888,1228,911],{"class":910},[888,1230,1231,1234,1237,1240],{"class":890,"line":925},[888,1232,1233],{"class":910},"  --secret",[888,1235,1236],{"class":897}," variable:access_token",[888,1238,1239],{"class":910}," --drop",[888,1241,1242],{"class":897}," auth:apikey\n",[888,1244,1246],{"class":890,"line":1245},4,[888,1247,1248],{"emptyLinePlaceholder":226},"\n",[888,1250,1252],{"class":890,"line":1251},5,[888,1253,1255],{"class":1254},"sJ8bj","# or decide everything the same way\n",[888,1257,1259,1261,1263,1265,1267,1269],{"class":890,"line":1258},6,[888,1260,894],{"class":893},[888,1262,898],{"class":897},[888,1264,901],{"class":897},[888,1266,1216],{"class":897},[888,1268,907],{"class":897},[888,1270,1271],{"class":910}," --secret-all\n",[793,1273,1274],{},"On a terminal, candidates you didn't pass are asked interactively. In a pipeline the command fails\nand lists them. The import refuses an API slug that already exists: it always creates a new API.",[1276,1277,1278],"note",{},[793,1279,1280,1281,1091,1284,1081,1287,1290,1291,1074],{},"A credential typed directly in an auth tab is always moved behind a variable (",[837,1282,1283],{},"bearerToken",[837,1285,1286],{},"basicPassword",[837,1288,1289],{},"apiKeyValue","), whatever you decide: the decision only says whether its value is\nwritten to ",[837,1292,1293],{},".secrets.env",[842,1295,1297],{"id":1296},"what-gets-converted","What gets converted",[935,1299,1300,1310],{},[938,1301,1302],{},[941,1303,1304,1307],{},[944,1305,1306],{},"Postman",[944,1308,1309],{},"API Craft",[951,1311,1312,1320,1333,1348,1367,1379,1394,1416,1429,1440,1448,1460],{},[941,1313,1314,1317],{},[956,1315,1316],{},"Request",[956,1318,1319],{},"A request instance under a defined operation. Requests sharing a method and path share the operation.",[941,1321,1322,1325],{},[956,1323,1324],{},"Folders",[956,1326,1327,1328,1332],{},"Not reproduced: the mapper groups by path, as for an OpenAPI import. Regroup with ",[812,1329,1331],{"href":1330},"\u002Fdocs\u002Fguides\u002Fimporting-a-spec#handling-unmapped-operations","schema rules"," if needed.",[941,1334,1335,1341],{},[956,1336,1337,1340],{},[837,1338,1339],{},"{{baseUrl}}\u002F…"," (any leading host variable)",[956,1342,1343,1344,1347],{},"The API base URL ",[837,1345,1346],{},"{{baseUrl}}",", with one value per environment. Requests on another host become standalone instances.",[941,1349,1350,1360],{},[956,1351,1352,1355,1356,1359],{},[837,1353,1354],{},":id"," and ",[837,1357,1358],{},"{{var}}"," path segments",[956,1361,1362,1363,1366],{},"Path parameters (",[837,1364,1365],{},"{id}","), with the request's value on the instance.",[941,1368,1369,1372],{},[956,1370,1371],{},"Collection variables",[956,1373,1374,1375,1378],{},"The ",[837,1376,1377],{},"local"," environment.",[941,1380,1381,1383],{},[956,1382,139],{},[956,1384,1385,1386,1389,1390,1393],{},"One environment each, named after the file's environment; the level comes from the name (",[837,1387,1388],{},"prod"," → production, ",[837,1391,1392],{},"staging"," → staging, otherwise local). An environment value wins over the collection variable, as in Postman.",[941,1395,1396,1399],{},[956,1397,1398],{},"Variable names",[956,1400,1401,1402,1405,1406,1081,1409,1405,1412,1415],{},"camelCase (",[837,1403,1404],{},"base_url"," → ",[837,1407,1408],{},"baseUrl",[837,1410,1411],{},"page-size",[837,1413,1414],{},"pageSize","); every reference is rewritten.",[941,1417,1418,1421],{},[956,1419,1420],{},"Bearer, API key, basic auth",[956,1422,1423,1424,1428],{},"The same ",[812,1425,1427],{"href":1426},"\u002Fdocs\u002Fguides\u002Fauth-and-middlewares#declarative-auth","declarative auth",". Collection auth becomes the API default; folder and request auth that differs lands on the instances; \"No auth\" stays explicit.",[941,1430,1431,1434],{},[956,1432,1433],{},"JSON, text, XML, urlencoded and GraphQL bodies",[956,1435,1436,1437,1044],{},"The instance body (GraphQL as JSON ",[837,1438,1439],{},"{ query, variables }",[941,1441,1442,1445],{},[956,1443,1444],{},"Saved examples",[956,1446,1447],{},"Response codes and body schemas in the operation's contract.",[941,1449,1450,1453],{},[956,1451,1452],{},"Pre-request scripts",[956,1454,1455,1456,1459],{},"One ",[837,1457,1458],{},"before"," middleware per script, chained on each instance in Postman order: collection, folders, request.",[941,1461,1462,1465],{},[956,1463,1464],{},"Test scripts",[956,1466,1467,1468,1471,1472,1475,1476,1479],{},"One workflow per tested request, ",[837,1469,1470],{},"\u003Capi>-\u003Crequest>",": a ",[837,1473,1474],{},"request"," block, then one ",[837,1477,1478],{},"assert"," block per test script (collection, folders, request).",[1481,1482,1484],"h3",{"id":1483},"scripts-copied-never-translated","Scripts: copied, never translated",[793,1486,1487,1488,1491,1492,1494],{},"There is no ",[837,1489,1490],{},"pm.*"," compatibility layer. Each script is written in full, line by line in comments,\nunder a ",[837,1493,839],{}," that fails until you rewrite it:",[879,1496,1500],{"className":1497,"code":1498,"language":1499,"meta":884,"style":884},"language-ts shiki shiki-themes github-light github-dark","\u002F\u002F apis\u002Fpetstore\u002Fmiddlewares\u002Fcollection-pre-request.ts\nimport type { BeforeRequestContext } from '@apicrafthq\u002Fscript-sdk'\n\nexport const handle = async (ctx: BeforeRequestContext): Promise\u003Cvoid> => {\n    throw new Error('Imported Postman pre-request script, not converted. …')\n\n    \u002F\u002F --- Postman pre-request script of Collection (not executable) ---\n    \u002F\u002F pm.request.headers.add({ key: 'X-Request-Id', value: pm.variables.replaceIn('{{$guid}}') });\n}\n","ts",[837,1501,1502,1507,1525,1529,1582,1602,1606,1612,1618],{"__ignoreMap":884},[888,1503,1504],{"class":890,"line":172},[888,1505,1506],{"class":1254},"\u002F\u002F apis\u002Fpetstore\u002Fmiddlewares\u002Fcollection-pre-request.ts\n",[888,1508,1509,1512,1515,1519,1522],{"class":890,"line":914},[888,1510,298],{"class":1511},"szBVR",[888,1513,1514],{"class":1511}," type",[888,1516,1518],{"class":1517},"sVt8B"," { BeforeRequestContext } ",[888,1520,1521],{"class":1511},"from",[888,1523,1524],{"class":897}," '@apicrafthq\u002Fscript-sdk'\n",[888,1526,1527],{"class":890,"line":925},[888,1528,1248],{"emptyLinePlaceholder":226},[888,1530,1531,1534,1537,1540,1543,1546,1549,1553,1556,1559,1562,1564,1567,1570,1573,1576,1579],{"class":890,"line":1245},[888,1532,1533],{"class":1511},"export",[888,1535,1536],{"class":1511}," const",[888,1538,1539],{"class":893}," handle",[888,1541,1542],{"class":1511}," =",[888,1544,1545],{"class":1511}," async",[888,1547,1548],{"class":1517}," (",[888,1550,1552],{"class":1551},"s4XuR","ctx",[888,1554,1555],{"class":1511},":",[888,1557,1558],{"class":893}," BeforeRequestContext",[888,1560,1561],{"class":1517},")",[888,1563,1555],{"class":1511},[888,1565,1566],{"class":893}," Promise",[888,1568,1569],{"class":1517},"\u003C",[888,1571,1572],{"class":910},"void",[888,1574,1575],{"class":1517},"> ",[888,1577,1578],{"class":1511},"=>",[888,1580,1581],{"class":1517}," {\n",[888,1583,1584,1587,1590,1593,1596,1599],{"class":890,"line":1251},[888,1585,1586],{"class":1511},"    throw",[888,1588,1589],{"class":1511}," new",[888,1591,1592],{"class":893}," Error",[888,1594,1595],{"class":1517},"(",[888,1597,1598],{"class":897},"'Imported Postman pre-request script, not converted. …'",[888,1600,1601],{"class":1517},")\n",[888,1603,1604],{"class":890,"line":1258},[888,1605,1248],{"emptyLinePlaceholder":226},[888,1607,1609],{"class":890,"line":1608},7,[888,1610,1611],{"class":1254},"    \u002F\u002F --- Postman pre-request script of Collection (not executable) ---\n",[888,1613,1615],{"class":890,"line":1614},8,[888,1616,1617],{"class":1254},"    \u002F\u002F pm.request.headers.add({ key: 'X-Request-Id', value: pm.variables.replaceIn('{{$guid}}') });\n",[888,1619,1621],{"class":890,"line":1620},9,[888,1622,1623],{"class":1517},"}\n",[793,1625,1626,1627,1630,1631,1634],{},"Line comments are used (never ",[837,1628,1629],{},"\u002F* *\u002F","), so a script containing ",[837,1632,1633],{},"*\u002F"," can't break the file, and the\nproject always builds. Collection and folder pre-request scripts are one middleware shared by every\nrequest they applied to, so you rewrite them once. Test scripts are copied into each workflow,\nbecause workflow scripts belong to their workflow.",[842,1636,1043],{"id":1637},"what-isnt-converted",[793,1639,1640,1641,1643],{},"Everything below is listed in the plan under ",[837,1642,1036],{},", with where it was found:",[935,1645,1646,1656],{},[938,1647,1648],{},[941,1649,1650,1653],{},[944,1651,1652],{},"Kind",[944,1654,1655],{},"Why, and what to do",[951,1657,1658,1672,1685,1698,1714],{},[941,1659,1660,1665],{},[956,1661,1662],{},[837,1663,1664],{},"setNextRequest",[956,1666,1667,1668,1074],{},"Postman's runner ordering has no equivalent. Rebuild the sequence as one workflow by ",[812,1669,1671],{"href":1670},"\u002Fdocs\u002Fguides\u002Fwriting-workflows#moving-blocks-between-workflows","moving blocks",[941,1673,1674,1682],{},[956,1675,1676,1013,1679],{},[837,1677,1678],{},"formdata",[837,1680,1681],{},"binaryBody",[956,1683,1684],{},"Multipart and file bodies are not supported yet; the body is left out.",[941,1686,1687,1692],{},[956,1688,1689],{},[837,1690,1691],{},"unparsedJson",[956,1693,1694,1695,1697],{},"A raw JSON body that doesn't parse (an unquoted ",[837,1696,1358],{},", a comment). Kept as text; fix it in the request.",[941,1699,1700,1705],{},[956,1701,1702],{},[837,1703,1704],{},"dynamicVariable",[956,1706,1707,1081,1710,1713],{},[837,1708,1709],{},"{{$guid}}",[837,1711,1712],{},"{{$timestamp}}","… are kept as typed and won't resolve. Generate the value in a middleware.",[941,1715,1716,1721],{},[956,1717,1718],{},[837,1719,1720],{},"complexAuth",[956,1722,1723,1724,1728,1729,1044],{},"OAuth2, digest, AWS signature… become a ",[812,1725,1727],{"href":1726},"\u002Fdocs\u002Fguides\u002Fauth-and-middlewares#custom-auth","custom auth"," script with the configuration commented out (literal values shown as ",[837,1730,1731],{},"\u003Credacted>",[842,1733,1735],{"id":1734},"_4-finish-the-migration","4. Finish the migration",[1737,1738,1739,1748,1892,1902,1914],"ol",{},[808,1740,1741,1744,1745,1747],{},[797,1742,1743],{},"Fill the secrets"," you dropped: in each environment's ",[837,1746,1293],{},", or the environment view\nin the app.",[808,1749,1750,1753,1754,1877,1880,1881,1883,1884,1886,1887,1044],{},[797,1751,1752],{},"Rewrite the scripts."," Start with the middlewares (every request using them fails until they\nare rewritten), then the test workflows. A Postman test usually becomes a few lines:",[879,1755,1757],{"className":1497,"code":1756,"language":1499,"meta":884,"style":884},"\u002F\u002F Postman: pm.test('found', () => pm.response.to.have.status(200));\nimport type { AssertContext } from '@apicrafthq\u002Fscript-sdk'\n\nexport const run = (ctx: AssertContext): void => {\n  const status = ctx.blockResult('request').response?.status\n  if (status !== 200) throw new Error(`expected 200, got ${status}`)\n}\n",[837,1758,1759,1764,1777,1781,1813,1837,1873],{"__ignoreMap":884},[888,1760,1761],{"class":890,"line":172},[888,1762,1763],{"class":1254},"\u002F\u002F Postman: pm.test('found', () => pm.response.to.have.status(200));\n",[888,1765,1766,1768,1770,1773,1775],{"class":890,"line":914},[888,1767,298],{"class":1511},[888,1769,1514],{"class":1511},[888,1771,1772],{"class":1517}," { AssertContext } ",[888,1774,1521],{"class":1511},[888,1776,1524],{"class":897},[888,1778,1779],{"class":890,"line":925},[888,1780,1248],{"emptyLinePlaceholder":226},[888,1782,1783,1785,1787,1790,1792,1794,1796,1798,1801,1803,1805,1808,1811],{"class":890,"line":1245},[888,1784,1533],{"class":1511},[888,1786,1536],{"class":1511},[888,1788,1789],{"class":893}," run",[888,1791,1542],{"class":1511},[888,1793,1548],{"class":1517},[888,1795,1552],{"class":1551},[888,1797,1555],{"class":1511},[888,1799,1800],{"class":893}," AssertContext",[888,1802,1561],{"class":1517},[888,1804,1555],{"class":1511},[888,1806,1807],{"class":910}," void",[888,1809,1810],{"class":1511}," =>",[888,1812,1581],{"class":1517},[888,1814,1815,1818,1821,1823,1826,1829,1831,1834],{"class":890,"line":1251},[888,1816,1817],{"class":1511},"  const",[888,1819,1820],{"class":910}," status",[888,1822,1542],{"class":1511},[888,1824,1825],{"class":1517}," ctx.",[888,1827,1828],{"class":893},"blockResult",[888,1830,1595],{"class":1517},[888,1832,1833],{"class":897},"'request'",[888,1835,1836],{"class":1517},").response?.status\n",[888,1838,1839,1842,1845,1848,1851,1854,1856,1858,1860,1862,1865,1868,1871],{"class":890,"line":1258},[888,1840,1841],{"class":1511},"  if",[888,1843,1844],{"class":1517}," (status ",[888,1846,1847],{"class":1511},"!==",[888,1849,1850],{"class":910}," 200",[888,1852,1853],{"class":1517},") ",[888,1855,839],{"class":1511},[888,1857,1589],{"class":1511},[888,1859,1592],{"class":893},[888,1861,1595],{"class":1517},[888,1863,1864],{"class":897},"`expected 200, got ${",[888,1866,1867],{"class":1517},"status",[888,1869,1870],{"class":897},"}`",[888,1872,1601],{"class":1517},[888,1874,1875],{"class":890,"line":1608},[888,1876,1623],{"class":1517},[1878,1879],"br",{},"Some assertions don't need a script at all: an ",[837,1882,1478],{}," block can check ",[837,1885,1867],{},", headers and\nbody fields declaratively (see ",[812,1888,1890],{"href":1889},"\u002Fdocs\u002Fguides\u002Fwriting-workflows#assert",[837,1891,1478],{},[808,1893,1894,1897,1898,1901],{},[797,1895,1896],{},"Regroup the workflows."," The import makes one workflow per tested request on purpose: whether a\nfolder was a sequence or just storage is not in the file. Drag blocks onto another workflow in\nthe sidebar (or ",[837,1899,1900],{},"craftr workflow move-block",") to build real scenarios.",[808,1903,1904,1907,1908,1911,1912,1044],{},[797,1905,1906],{},"Correct the contracts."," Inferred schemas come from samples. Fix parameters, the request body and\nresponses in the operation's ",[797,1909,1910],{},"Definition"," tab\n(see ",[812,1913,65],{"href":66},[808,1915,1916,1919],{},[797,1917,1918],{},"Promote to a spec"," when you're happy with it, to get a real OpenAPI file for the API.",[1276,1921,1922],{},[793,1923,1924],{},"Without a Pro license an API can have 2 environments and a project 3 workflows. An import that would\ngo over refuses before writing anything; import fewer environment files or upgrade.",[1926,1927,1928],"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);}html pre.shiki code .sJ8bj, html code.shiki .sJ8bj{--shiki-default:#6A737D;--shiki-dark:#6A737D}html pre.shiki code .szBVR, html code.shiki .szBVR{--shiki-default:#D73A49;--shiki-dark:#F97583}html pre.shiki code .sVt8B, html code.shiki .sVt8B{--shiki-default:#24292E;--shiki-dark:#E1E4E8}html pre.shiki code .s4XuR, html code.shiki .s4XuR{--shiki-default:#E36209;--shiki-dark:#FFAB70}",{"title":884,"searchDepth":914,"depth":914,"links":1930},[1931,1932,1933,1934,1937,1938],{"id":844,"depth":914,"text":845},{"id":873,"depth":914,"text":874},{"id":1067,"depth":914,"text":1068},{"id":1296,"depth":914,"text":1297,"children":1935},[1936],{"id":1483,"depth":925,"text":1484},{"id":1637,"depth":914,"text":1043},{"id":1734,"depth":914,"text":1735},"Import a Postman collection and its environments into a new API, decide what is secret, then finish the migration by hand where Postman's behaviour can't be translated.","md","2026-10-25T21:36:21+01:00",{},null,{"title":57,"description":1939},"3P_lUvRhuBUUYYEN5aeeJEFlJaDrK6Utacd6i978Meg",[1947,1948],{"path":49,"title":48},{"path":6,"title":1949},"Documentation",1793542849732]