Dify custom tools from OpenAPI specifications: when a schema import beats writing a plugin
Dify can import an OpenAPI or Swagger schema as a custom tool without writing plugin code, so a team that needs a workflow or agent in a self-hosted Dify to call an internal REST API can often skip plugin development entirely. Each operation in the schema becomes a callable tool, and its parameters and descriptions are presented to workflows and agents. An agent chooses among these tools based on the text in the spec, so vague summary values, missing parameter descriptions and unclear operationId names lead to wrong calls. Treat the schema as part of the product: review it, remove operations you do not want exposed, and fix descriptions before import. Confirm in the Dify docs for your version which schema versions and file formats the importer accepts.
The outbound request does not go straight from Dify to your API. Outbound traffic is routed through the SSRF proxy configured by the SSRF_PROXY settings, and that proxy blocks internal and private IP ranges, which keeps a tool from being pointed at private addresses. The practical consequence is that an internal API host fails until you add an explicit allowance for it. Plan that change with your network and security team as a documented, narrow rule, and confirm in the Dify environment variable reference how the allowance is expressed for your version. Static credentials such as an API key or bearer token are set on the tool, so confirm where Dify stores them and who can read them in the console.
Choose the schema import when the API is plain REST, each operation maps to a single call, and authentication is a static key or token that the tool owner can supply. Move to a tool plugin when you need per-user OAuth, multi-step calls, response reshaping, or logic a schema cannot express. Before you commit, run the imported tools in a test workspace against a staging API, check that the agent selects and fills them correctly, and record the Dify version you tested, because minor releases arrive roughly monthly according to the GitHub release history. Confirm in the Dify docs for that version any limits on timeouts, response size and nested request bodies.
What you need before importing a schema
Most failed custom tool imports trace back to a missing prerequisite rather than a bad schema. The cards below cover the Dify deployment, the API specification, credentials, network paths and certificate trust that have to be in place before the first import.
A supported Dify deployment
Confirm the target Dify version and that the Docker Compose host meets the documented minimums: at least 2 CPU cores, 4 GB of RAM and Docker Compose 2.24.0 or later. The stack includes the api, worker and plugin daemon services, so OpenAPI tools depend on those components running correctly. Record the exact version now, because the import screen and tool behavior can differ between releases. Check the upgrade guide for that version before you change anything.
A reviewed OpenAPI or Swagger file
Export the specification from the API's source repository or gateway, not from a copy someone pasted into a wiki. Review it for operations that should not be exposed to a language model, such as deletes or bulk exports, and for descriptions clear enough for the model to choose the right operation. Confirm which specification version Dify accepts in its current documentation, and test the file with a validator before import.
A dedicated service account or key
Create a service identity for Dify with the narrowest permissions the selected operations need, rather than reusing a personal token. Decide who owns rotation and how the credential is stored, since Dify keeps it inside the tool configuration. Confirm with the API owner whether the endpoints accept API keys, bearer tokens or OAuth client credentials, because the authentication options you configure must match what the gateway enforces.
Network path from Dify to the host
Identify which Dify component makes the outbound call and confirm it can reach the internal hostname and port. Outbound requests pass through the SSRF proxy, which blocks internal and private IP ranges by default, so the destination must be added to the allowlist through the documented settings. Ask the network team to confirm firewall rules from the Dify host, and test the route from the same container network the tool will use.
Certificate trust for internal endpoints
If the API uses an certificate issued by an internal certificate authority, the Dify components that call it must trust that chain. Obtain the root and intermediate certificates from the PKI team and confirm how your Docker Compose deployment mounts and trusts custom CA files. Test with a request from inside the container, because a browser that trusts the certificate does not prove that Dify does.
A named owner and change record
Assign one owner for the tool who approves each schema change, credential rotation and endpoint addition. Keep the exported schema, its version and the Dify version in the same change record so that a later failure can be traced to a specific combination. Plan a test environment that mirrors the production API before any production import.
How to import the schema and configure the tool
This sequence turns an internal REST API described by an OpenAPI or Swagger file into a Dify custom tool that workflows and agents can call. Each step ends with a check, so you know the schema, credentials and network path work before the tool reaches production.
Export a clean schema from the API
The API owner exports the OpenAPI or Swagger document from the service or its repository, then checks it before Dify sees it. Confirm every operation has an operationId, a clear summary, typed parameters and documented response schemas, and remove endpoints that should never be called by an agent, such as administrative or destructive routes. Confirm the file validates with an OpenAPI validator and that it contains no internal secrets or example tokens. Done means the file validates cleanly and contains only the operations you intend to expose.
Create the custom tool from the schema
In the Dify console, open the workspace tools area, choose to create a custom tool, and import the schema by pasting the content or uploading the file. Dify parses the document and lists the operations it found as separate tool functions. Confirm that each intended operation appears with the parameter names and descriptions you expect, and that the parsing did not silently drop routes. Done means the parsed operation list matches the export you checked in the previous step.
Set the server URL and authentication method
Set the server URL to the base address of the internal API as the Dify API and SSRF proxy will reach it, which may differ from the address your browser uses. Choose the authentication method the API requires, such as an API key sent in a header or a bearer token, and enter the credential so it is stored as a workspace secret rather than in the schema. Use a dedicated service account with the least privilege the tool needs. Done means the credential is saved and the server URL resolves from the Dify API container.
Test each operation from the tool panel
Open each operation in the tool panel and run it with sample inputs that you know are safe, starting with read-only GET operations. Compare the returned status code and response body with what the API owner expects, and check that parameters are mapped to the correct path, query or body fields. Repeat for write operations only in a non-production environment with reversible test data. Done means every intended operation returns the expected response, and any failure is traced to a schema, credential or network cause before the tool is used.
Confirm the request reached the internal host
Check the platform logs or the internal API access logs for the test calls made in the previous step. The API log should show a request from the Dify side with the expected path, method and service account, and the response code should match the tool panel result. If the request is blocked, look for an SSRF proxy denial and add the internal host to the allowlist through the documented configuration, keeping the entry as narrow as possible. Done means you can point to a log entry for each successful test call.
Add the tool to a workflow or agent
In the app editor, add the custom tool as a node in a workflow or as a tool available to an agent, and select only the operations that app needs. Write clear tool descriptions and parameter hints so the model or the workflow maps inputs correctly, and map any user input explicitly rather than letting free text reach write operations. Run the app in preview with a test prompt and confirm the tool is invoked and its output appears in the trace. Done means the trace shows one correct tool call with the expected arguments and response.
Publish the tool and record its configuration
Publish the app version that uses the tool and record the schema version, the server URL, the service account name and the operations enabled, in your change record or configuration repository. Keep the credential in the secret store and note who can rotate it. Re-test after any schema change or API upgrade, because a changed operation signature can break the tool without an obvious error in the app. Done means the published version is documented and a re-test procedure is assigned to a named owner.
How schema fields map to tool parameters and credentials
This table pairs common OpenAPI elements with the Dify tool field, workflow input or credential setting they feed, and says who supplies each value. Read it while importing a schema, then check each mapping against the schema your API actually publishes, because generated fields follow the document exactly.
| OpenAPI element | Where it lands in Dify | Who fills it | What to verify |
|---|---|---|---|
| operationId | Tool name the model sees and selects | Schema author, set at import | Names are unique and descriptive enough for the model to choose the right operation |
| Summary and description | Tool description guiding model selection | Schema author, edited in Dify | Text tells the model when to call the tool and what it returns |
| Path parameters | Required tool parameters in the URL path | Model fills from conversation | Values are validated against the expected format before the call |
| Query parameters | Tool parameters, optional or required per schema | Model fills, operator can set fixed values | Required flags match the API's actual behavior |
| Request body schema | Tool parameters built from JSON properties | Model fills, operator restricts fields | Nested objects and enums import as the API expects |
| Response schema | Tool output the workflow reads downstream | API returns, workflow maps selected fields | Sample responses match the schema, including error bodies |
| Security scheme (API key, bearer, basic) | Authorization settings on the tool provider | Operator enters the credential once | Header name and location match what the gateway expects |
| Server URL | Base address for every call | Operator sets, often per environment | Internal hostname resolves and is on the SSRF proxy allowlist |
Choosing an authentication pattern for the imported tool
A static API key is the simplest pattern to configure. The OpenAPI schema declares the security scheme, and the key is entered once in the tool's credentials so that every call from the workflow carries the same value, either in a header such as X-API-Key or as a query parameter. Query parameters are the weaker choice because URLs tend to appear in proxy logs, web server access logs and browser history, so prefer a header whenever the target API accepts one.
- Audit trail: every call looks identical to the target system, so the API sees the key owner and not the Dify user or workflow that triggered the call.
- Rotation: changing the key requires updating the tool credential in Dify and in every workflow or app that depends on it, so plan a maintenance window.
- User attribution: none. Requests cannot be tied to the person who asked the agent to act.
- Scope: keep the key read-only where the API allows it, and issue a separate key for each tool rather than sharing one across several integrations.
- Storage: Dify stores tool credentials in its database, so confirm how the key is encrypted at rest under your
SECRET_KEYand workspace encryption settings.
Confirm in the Dify docs which credential fields the OpenAPI import exposes for API key schemes, and check whether your target API supports header-based keys before you design around query parameters.
A bearer token issued to a dedicated service account is the common middle option. The OpenAPI schema declares an HTTP bearer scheme, and the token is supplied as an Authorization: Bearer header. The identity belongs to the integration, not to a person, so the token survives staff changes, but every Dify user who runs the tool acts with the same permissions.
- Audit trail: the target system records the service account, which is useful for system-level logs but does not show which Dify user or app made the call unless the API accepts a forwarded identifier.
- Rotation: short-lived tokens issued by your identity provider need a refresh mechanism. A static long-lived token has the same rotation burden as an API key.
- Least privilege: create a service account scoped to the operations the workflow needs, and avoid reusing an administrator account.
- Blast radius: a leaked token exposes everything the service account can reach, across all workspaces where the tool is installed.
- Separation: use one service account per environment, so staging workflows cannot call production systems.
Confirm whether the bearer scheme in your schema is imported with a credential field in your Dify version and whether token refresh is handled by the tool or must be managed outside Dify.
When the target system must know which person acted, each user needs their own grant. Dify's OpenAPI import is not the path for this. Per-user OAuth usually requires an OAuth-based tool plugin that handles the authorization flow, stores tokens per user and refreshes them. The plugin decision and its packaging are covered in the plugin pages of this series, so treat this option as a design requirement at this stage.
- Audit trail: the strongest option, because the target system records the individual user behind each call.
- Rotation: handled by the identity provider and the plugin's token refresh logic, which reduces manual key changes but adds failure modes when grants expire or users leave.
- Consent and scope: each user consents to scopes, so review which scopes the plugin requests before rollout.
- Build effort: a plugin adds design, build, testing and distribution work that a schema import does not require.
- Identity alignment: confirm how Dify's sign-in and your identity provider map to the user identities the target API expects.
Confirm with the Dify documentation which authentication types the OpenAPI import supports directly, and which require a plugin, before you commit to an option.
Reaching internal hosts through the SSRF proxy allowlist
Dify's SSRF proxy blocks internal and private address ranges by default, which is the right starting point for a shared platform. An OpenAPI tool that calls an internal service only works once that host is allowed on purpose, so each entry should be deliberate, narrow and tested.
Why the default blocks internal hosts
The SSRF_PROXY settings route outbound requests from Dify through a proxy that blocks internal and private IP ranges. An OpenAPI tool that targets an internal REST API will fail with a connection or access error until that host is permitted. Treat the failure as the control working, not as a bug in the tool. Confirm the exact proxy and allowlist configuration keys in the Dify environment variable reference before you edit any .env file, because key names can change between releases.
Allow named hosts and ports only
Add the specific hostname or address of each API the tool calls, and the port it listens on, rather than opening a whole subnet. A single entry for an inventory API on one port is far easier to review than a range covering a data center. Record the owner, the business reason and the date each entry was added, so the list can be audited when a service is retired.
Keep the allowlist minimal
Every entry widens what any tool or workflow in the platform can reach, not only the one that needs it. Review the list against the set of OpenAPI tools that are actually published, and remove entries when a tool is deprecated. Ask whether a read-only service account on a gateway in front of the API would let you allow one endpoint instead of a whole application server.
Check DNS resolution behavior
The proxy decides based on the address a name resolves to, so a hostname that resolves to a private address can be blocked even when the name looks external. Also check the reverse case: a name that changes its address after you approve it can route traffic somewhere you did not review. Ask your network team which resolvers the SSRF proxy uses, whether records are cached, and how a change in DNS for an internal service will reach Dify.
Re-test after every change
After adding, changing or removing an allowlist entry, run each affected tool against a test record and confirm both sides: the approved host answers, and an unapproved internal address is still refused. Repeat the test after Dify upgrades, because proxy behavior is part of the security model and release notes can change it. Keep the test results with your change record.
Why an imported Dify tool fails and how to fix it
This table pairs each failure an OpenAPI-based Dify tool typically shows with its likely cause and the fix to try first. Read it in order when a tool fails after import, since schema problems surface before authentication and network problems appear only at call time.
| Failure | Likely cause | Fix |
|---|---|---|
| Schema import error | The spec is invalid, uses a Swagger or OpenAPI construct the importer does not accept, or has unresolved references | Validate the file with an OpenAPI linter, resolve $ref links, remove unsupported constructs and re-import the corrected file |
| 401 or 403 on tool call | The credential is missing, expired, sent in the wrong header or placed in the wrong authentication field | Confirm the auth type set on the tool matches the API, re-enter the key in the tool credentials and test the endpoint directly with the same header |
| Request blocked by the SSRF proxy | The tool targets a private or internal address that the SSRF proxy denies by default | Confirm the internal host is permitted in the SSRF proxy configuration, then restart the affected services and retest; keep the allowlist as narrow as possible |
| TLS trust error with an internal CA | The Dify container does not trust the internal certificate authority that signed the API certificate | Add the internal root and intermediate certificates to the container trust store used by Dify, then rebuild or restart the containers and retest |
| Wrong server URL after an environment change | The tool still points to the old host, port or path from the original import | Update the server URL in the tool definition or the spec's servers entry, then re-check the base path for each environment |
| Tool stops working after an upgrade | A new Dify release changed security defaults, the proxy path or the environment variables the tool depends on | Compare the release notes and the .env.example file for the target version, reapply local settings, then retest every imported tool in staging before production |
Questions teams ask before importing an internal API into Dify
How much effort does an OpenAPI tool take compared with a tool plugin?
An OpenAPI tool usually takes less effort than a tool plugin because it avoids writing, packaging and signing plugin code. You import a schema, configure authentication and test the operations you need. A tool plugin adds a development project with its own build, packaging, versioning and distribution steps, which pays off when the logic goes beyond calling HTTP endpoints. The real effort in either case sits in the API itself: whether its schema is accurate, its errors are predictable and its authentication suits a service account. Ask for the operations in scope and a review of the schema before estimating anything.
What drives the work when importing an internal API into Dify?
Four factors shape the work more than any others:
- Schema quality: complete operation descriptions, parameter types, required fields and response models make tools easier for models to call correctly.
- Auth model: API keys, bearer tokens and OAuth flows differ in how credentials are stored and refreshed.
- Number of operations: each exposed operation needs testing, naming and description review.
- Network allowlisting: internal hosts must be reachable through the SSRF proxy configuration, which needs security review.
A well-documented API with one auth method and a few operations is a small job. A large, loosely documented API with several auth schemes is a much larger one.
Can our own team import an internal API into Dify without a partner?
Yes, many teams can do a single, well-scoped import with their own staff, provided someone understands the API, can test it in a non-production environment and can change Dify's environment configuration. The work becomes harder when several APIs need consistent naming, when credentials must be managed per workspace, or when the SSRF proxy allowlist needs review from security. Consider whether your team can own the upgrade path as well, since Dify ships minor releases roughly monthly and each change to tool configuration should be retested. A partner is most useful when the team lacks time, experience with OpenAPI or a clear owner for ongoing changes.
What does DeployOpen need from our side before scoping an OpenAPI tool project?
DeployOpen typically needs four inputs to scope the work accurately:
- The OpenAPI or Swagger schema for the API, with its version and any known gaps
- A test environment where the API can be called safely with test credentials
- A named API owner who can answer questions about behavior, rate limits and data sensitivity
- A security sign-off path covering the authentication method, the internal hosts to be allowlisted and the operations that may be exposed to models
Agree these inputs before the written scope is drafted, since missing answers usually change the deliverables.
How long does it take to scope and deliver an OpenAPI tool project?
The duration depends on the written scope, so no fixed timeline applies. Scoping depends on how quickly the API owner and security team answer questions about the schema, authentication and network paths. Delivery depends on the number of operations, the complexity of authentication and the number of test rounds needed in your environment. Ask for a scope document that lists operations, auth method, hosts to allowlist, test cases and acceptance criteria, along with the dependencies that could move the schedule. Most engagements are fixed-scope and agreed in writing before work starts.
When is a tool plugin a better choice than an OpenAPI tool?
A tool plugin is the better choice when the integration needs logic that an HTTP call cannot express, such as multi-step request flows, custom token exchange, response transformation beyond simple mapping or per-user OAuth handled inside the plugin. It also suits cases where the tool must be versioned, signed and distributed to several workspaces as a package. If the API is already well described and each action maps to one endpoint, an OpenAPI tool is usually enough. Review the plugin type choice before committing, because switching later means reworking authentication and testing.
Which security risks come with calling internal hosts from Dify tools?
The main risk is that outbound requests from Dify can reach internal systems. Dify's SSRF_PROXY settings route outbound requests through a proxy that blocks internal and private IP ranges, so internal hosts must be deliberately allowed. Each allowlist entry widens what a workflow or model-driven tool can reach, so security teams should approve hosts, ports and methods individually. Service credentials should be scoped to read or write only what the tool needs, and stored through Dify's secret handling rather than in schema files. Confirm the exact allowlist settings against the environment variable reference for your Dify version.
Official Dify documentation to read alongside this page
Start with the Docker Compose deployment guide in the Dify self-hosting docs, because it shows how the api, worker, web, plugin daemon and SSRF proxy services are wired together in the stack you will be changing. The OpenAPI tool depends on the outbound path through the SSRF proxy, so confirm from that guide which proxy service runs in your deployment and how its container is named before you edit any allowlist. The guide also sets the minimum host requirements and Docker Compose version, which you should check against your current hosts before planning changes. Read the Docker Compose quick start against the tag you actually run, not the latest documentation.
The environment variable reference is where the settings that govern this integration live. Read the entries for the SSRF proxy, including how outbound requests are routed and which internal and private ranges are blocked, and the entries that control how the plugin daemon and API service communicate. Record the exact variable names and defaults for your version in your deployment repository, because a change to .env is not picked up until the affected containers are recreated. Treat SECRET_KEY as a value you never rotate casually, since changing it logs out all users. The environment variable reference is the source to check for each of these keys.
The GitHub releases page tells you what changed between your current version and the target version, including security changes to the sandbox, proxy and inter-service authentication that can affect how an internal API is reached. Read the release notes and the upgrade guide for every version between your current release and the target before you change an allowlist or a tool definition. Minor releases have been arriving roughly monthly, so a tool that works today can behave differently after an upgrade. Confirm the behavior of any imported schema and any network rule by testing it on a staging instance first. The releases page is the record of those changes.
How DeployOpen scopes and delivers Dify custom tool work
DeployOpen plans, builds, tests and documents Dify custom tools from OpenAPI specifications inside your own infrastructure, so the tool, its credentials and its network path are agreed before any work starts. Engagements are fixed-scope, with the deliverables and timeline set out in writing before work begins.
How we scope
- Inventory the internal REST APIs to expose, their OpenAPI or Swagger versions and the operations each tool should call
- Agree the authentication method per API, who owns each credential and how keys rotate
- Record which internal hosts must be reachable through the SSRF proxy allowlist and who approves each entry
How we build
- Import and review each schema in a non-production Dify workspace, correcting operation IDs, parameter descriptions and response shapes
- Configure authentication and test each operation against a staging copy of the internal API before any production import
- Verify that allowlist changes permit only the agreed hosts and ports, and that private ranges stay blocked otherwise
How we hand over
- Deliver the imported tool definitions, schema sources, allowlist changes and credential setup as versioned, documented artifacts
- Provide a runbook covering schema updates, credential rotation, allowlist requests and rollback steps
- Walk your platform and security teams through the test results, open risks and the decisions recorded during scoping
How we support
- Ongoing support, upgrades and continuous testing are available as a retainer, scoped in writing
- Re-check tool definitions and allowlist entries when a Dify upgrade or an internal API version change arrives
- Confirm with your team which support hours, response paths and change approvals apply before the retainer starts

