Internet Data Framework

Documentation for Internet Data Framework v1.1

What the Asset Does

Internet Data Framework helps you describe HTTP APIs in Unity, test requests inside the editor, and generate a C# client for runtime use.

Instead of manually building URLs, headers, auth, and request bodies in gameplay code, you keep the configuration in a Workspace, test endpoints ahead of time, and then use either the generated client or direct Workspace calls.

Typical workflow:

  1. Import OpenAPI / Swagger or create the API manually.
  2. Configure environments, auth, variables, and request rules.
  3. Test endpoints in the Request and Test tabs.
  4. Configure mocks and history if needed.
  5. Generate the client and use it in your project.

Basic Workflow

1. Open the Window

Open Tools / Internet Data Framework / Workspace.

This is the main window where you:

  • store your API definition;
  • configure environments;
  • create schemas;
  • test requests;
  • generate a C# client.

2. If You Already Have OpenAPI / Swagger, Import the API

If you already have a current OpenAPI / Swagger specification, this is the main and fastest path.

The workflow in this case is:

  1. Click Import, choose a JSON or YAML file, or paste its contents.
  2. Internet Data Framework will automatically create a Workspace, environments, endpoints, and schemas.
  3. Verify that endpoints, schemas, and related settings were created correctly after import.
  4. Adjust auth and request rules if needed.

Importing saves a lot of time and immediately gives you a ready API structure, a set of endpoints, and data models from an existing specification.

3. If You Do Not Have OpenAPI / Swagger, Create the Configuration Manually

If you do not have a ready specification, the basic flow looks like this:

  1. Create or select a Workspace.
  2. Configure an environment.
  3. Add endpoints.
  4. Create request and response schemas.
  5. Configure auth and request rules.

Workspace is the asset that stores the full configuration of your API.

4. Create a Workspace and Environment

If a Workspace does not exist yet:

  1. Click New.
  2. Select Workspace.
  3. Save the asset inside the Assets folder.
  4. When a Workspace is created, a Development Environment is created automatically. You can use it as-is, or delete it and create a new one.

In the Environments tab:

  1. Select or create an environment, for example Development, Staging, or Production.
  2. Set the Base URL of your API.
  3. Select an auth profile if needed.
  4. Make this environment active.

If you do not have a real API yet, you can enter any URL, for example https://example.com/.
In that case, you will need to enable mock responses to test requests.

5. Create Endpoints Manually

For each endpoint you usually need to fill in:

  • Path - the route relative to the Base URL, for example /players/{playerId}. A leading slash is optional;
  • Id - the unique identifier used to generate the method name. This is usually a readable name such as GetPlayerById;
  • Method - the HTTP method, for example GET, POST, PUT, PATCH, DELETE, HEAD, OPTIONS;
  • Path parameters, if the route contains variables such as {playerId};
  • Query parameters, if the endpoint accepts query string parameters, for example includeStats=true in /players?includeStats=true;
  • The request schema defines the body type for the endpoint. If it is set, the generated client uses it for a typed request parameter and body serialization. If no request schema is set, the endpoint remains without a typed body contract.
  • The response schema defines the result type of the endpoint. If it is set, the generated client returns a typed model. If no response schema is set, you do not get a typed response contract and handle the result in a more generic form.

You can also optionally configure:

  • Alias - an alternative name for the endpoint that can be used for method generation instead of Id. This is useful if Id contains symbols that are not suitable for method names, or if you want shorter and more convenient names.
  • Summary - a short description that can be used in documentation or comments for the generated method.
  • Deprecated - a flag that marks the endpoint as obsolete. Generated methods will be marked with [Obsolete]. This is useful for API lifecycle management and for informing developers that certain endpoints should not be used in new code.
  • Exclude From History - a flag that excludes requests to this endpoint from request history. This is useful for endpoints that are called very frequently or are not useful for analysis, such as health checks or current time endpoints.
  • Headers, Cookies, Auth, Cache - these let you add to or override settings defined on the environment for a specific endpoint. This is useful when certain endpoints require unique headers, authorization, or cache behavior that differs from the environment defaults.

6. Create Schemas Manually

A schema describes the structure of the data that an endpoint sends in the request body as JSON or receives in the response as JSON.

In practice, a schema defines a set of fields, their types, and their nesting. Based on schemas, Internet Data Framework can determine which C# type is required for a request and which type should be returned from the response.

Schemas are very useful because they greatly improve both convenience and reliability when working with APIs. It becomes much harder to make a mistake in the data structure or forget to include a required field.

In the Schemas tab, create your data models.

Basic setup usually looks like this:

  1. Id - the unique schema identifier used to generate the class name. This is usually a readable name such as Player or CreatePlayerRequest.
  2. Display Name - a user-friendly name that can be used in documentation or comments for the generated class.
  3. Description - a detailed description of the schema that can help explain its purpose and usage.
  4. Deprecated - a flag that marks the schema as obsolete. Generated classes will be marked with [Obsolete]. This is useful for data model lifecycle management and for informing developers that certain schemas should not be used in new code.
  5. Used In - the list of endpoints and schemas where this schema is used. This helps track where a given data model is used and can be useful for impact analysis when the schema changes.
  6. Fields - the set of fields that describe the data structure. For each field you usually specify:
    • Name - the field name used in JSON and in the C# class.
    • Required - whether this field must be provided. This affects data validation and helps clarify which data is required for the API to work correctly.
    • Type - the field data type, for example string, int, bool, or a reference to another schema for nested objects.
    • Array - a flag indicating that the field is an array. If enabled, the field type will be treated as an array of the selected type.
    • Description - a description of the field that can help developers understand its purpose and correct usage.

7. Configure Request Rules and Auth

After creating your API structure, configure request behavior.

This usually includes:

  • an auth profile in the Auth tab;
  • assigning the auth profile to an environment or a specific endpoint;
  • rules that affect how requests are sent and how parameters are handled;
  • overrides for individual endpoints when the shared environment settings are not enough.

Supported authorization options depend on your project configuration, but the typical set looks like this:

  • Bearer Token;
  • API Key/Header;
  • API Key/Query.

Recommended approach:

  1. First configure auth at the Workspace level if it is the same for most requests.
  2. Then override rules only where an endpoint actually differs.

This keeps the configuration cleaner and makes the generated client behave more predictably.

8. Test Requests

Auth: What to Configure First

In the Auth tab, you create authorization profiles that are then assigned to environments and individual endpoints.

A profile usually includes:

  • Id - the internal profile identifier;
  • Display Name - a user-friendly name shown in the UI;
  • Auth Type - the authorization type;
  • Value Source - where the token or key comes from;
  • extra Headers if they are needed together with authorization.

Basic setup options:

  1. Bearer Token - the token is sent in the Authorization header.
  2. Key Header - the API key is sent in the specified header.
  3. Key Query - the API key is sent in a query parameter.

Value Source usually has two forms:

  • Inline - the value is stored directly in the auth profile;
  • Variable - the value comes from a Workspace or environment variable.

For production configurations, it is usually safer to use Variable instead of Inline so tokens are not duplicated in several places.

Variables: Shared and Secret Values

In the Variables tab, store reusable values that are needed while building requests:

  • auth tokens;
  • API keys;
  • tenant id, region, language;
  • any service values that are repeated in headers, query, or body.

For each variable, set:

  • Key - the variable name;
  • Value - the value;
  • Secret - enable this if the value is a token, key, or other sensitive text.

A practical workflow usually looks like this:

  1. Create a variable named authToken.
  2. Mark it as Secret.
  3. In the auth profile, select Value Source = Variable.
  4. Set the key to authToken.

This separates the authorization strategy from the actual secret value.

It is also important to remember that runtime variables created through the Workspace API can temporarily override values from the Workspace, the environment, and the request. This is useful for login flows, refresh tokens, temporary sessions, and test switches without manually editing the asset.

Settings: Shared Workspace Rules

Before active testing, it is useful to open the Settings tab once and review the shared Workspace settings.

Minimum settings worth checking:

  • Metadata - Title, Version, Description, if you want to maintain the workspace as a documented asset;
  • Common Cache Policy - default cache behavior for endpoints that do not override cache locally;
  • Retry Policy - Timeout Seconds, Max Retry Count, Retry Base Delay, Retry On Network Error, Retry On 5xx / 429, Respect Retry-After;
  • Request Errors - how to handle errors if the generated client works without rethrowing exceptions;
  • Mask Secrets In URLs - whether to hide secrets in preview, history, and error messages.

If you are just starting the integration, the default values are usually enough. It is still worth checking Timeout Seconds and Mask Secrets In URLs.

Mocks: Testing Without a Real API

If the real API is not ready yet, unavailable, or unstable, use the Mocks tab.

Basic workflow:

  1. Create the endpoint as usual.
  2. Open Mocks.
  3. Create a mock for the required endpoint.
  4. Enable the mock with Enable.
  5. Choose the response source.

It is useful to understand the supported mock response types right away:

  • Original - use the original response without overriding it;
  • Body - return the specified raw body;
  • File - return the body from a file;
  • Schema - build a mock response from a schema.

You can also configure for a mock:

  • Status Code, if you need to test handling of 200, 401, 404, 429, 500, and other responses;
  • Delay, if you need to simulate a slow server;
  • extra Headers and Cookies;
  • separate cache settings for the mock response.

This is especially useful in three cases:

  1. You are designing the client and UI before the API is ready.
  2. You need to reproduce a rare error or edge case.
  3. You want to test retry behavior, timeouts, or error screens without depending on an external service.

Before generating the client, it is recommended to open the Request or Test tab and verify endpoints directly in the editor.

Basic flow:

  1. Select an endpoint.
  2. Check the URL, path/query parameters, body, headers, cookies, and auth.
  3. If needed, switch to Custom URL mode to test an arbitrary absolute URL that is not described in the Workspace.
  4. Run the request.
  5. Make sure the response, statuses, and authorization behave as expected.

In the Request tab it is useful to specifically inspect:

  • the final URL after path and query parameter substitution;
  • which headers and cookies will actually be sent;
  • which auth configuration was resolved after all rules and overrides;
  • whether the test call should be written to history via Save to History.

This is an important step because it lets you separate API description issues from gameplay code issues. If an endpoint already fails during editor testing, fix the Workspace first instead of looking for the problem in runtime logic.

History: How to Use Request History

The History tab is useful not only for looking at the past, but also for debugging the current configuration.

It helps you:

  • see editor and runtime requests in one place;
  • quickly find failed calls;
  • reopen requests and analyze them again;
  • control which calls are actually written to history.

For the first setup, it is useful to review:

  • Record Requests - which requests to save: editor, runtime, all, or none;
  • Max History Records - how many records to keep;
  • Clear History On Play Mode - whether to clear history when entering Play Mode.

If an endpoint is called too often and only clutters history, you can enable Exclude From History for it.

9. Generate the Client

Open the Generation tab.

Configure:

  • Namespace;
  • Class Name;
  • Dont Destroy On Load, if the generated component should survive scene changes. This option is enabled by default;
  • Static Methods, if you want a static calling style;
  • Request Errors, to choose how the generated client behaves on failed requests.

Request Errors is especially important:

  • ThrowException - the generated client throws WorkspaceClientException;
  • ReturnDefault - the generated client handles the error internally and returns default.

For production code, it is usually safer to use ThrowException if you want explicit control over errors in your own code.

Next:

  1. Click Regenerate.
  2. Review the generated code.
  3. Click Write File.
  4. Save the .cs file inside the Assets folder.

After that, Unity will import the class into the project, and you will be able to use it as a normal component or as an entry point for API calls.

Important: the generated client is created as a partial class.
This allows you to safely extend it in a separate .cs file without losing your changes after the next generation.

The practical meaning is:

  • the generated file remains fully controlled by the generator;
  • your runtime code, helper methods, events, or integration with gameplay systems live in a different partial file;
  • on regeneration, only the generated file is replaced, while your own code stays intact.

Example:

public partial class WorkspaceApi
{
    public void LogEnvironment() => Debug.Log(Workspace);
}

This approach is especially useful if you want to add:

  • convenient wrappers around frequently used API calls;
  • local gameplay logic tied to a specific API client;
  • initialization methods, events, debug utilities, and other code that should not be generated automatically.

10. Use the Client in Your Code

The generated client is usually used in one of two ways:

  • as a MonoBehaviour component on a scene object;
  • as a static access point if Static Methods is enabled. In that case you still need to add the generated class to the scene, but it will behave like a singleton and expose static methods for API calls.

If Dont Destroy On Load is enabled, the component will not be destroyed when a new scene loads. This is useful when the API client should live throughout the whole gameplay session and keep the same reference to Workspace.

This option is usually left enabled if:

  • the API client is used across many scenes;
  • you call the API through Static Methods;
  • you need one long-lived singleton object for network access.

You can disable it if you want the client to exist only within a specific scene and be destroyed together with it.

Example with static methods:

var result = await WorkspaceApi.GetPlayer();

Example with a component reference:

[SerializeField] private WorkspaceApi api;

var result = await api.GetPlayer();

If you need to call an endpoint not through a generated method, but directly by its Id or Alias, you can use Workspace or WorkspaceClient.

Example call by endpoint id:

[SerializeField] private Workspace workspace;

UserListResponse result = await workspace.Execute<UserListResponse>("users.list");

This is useful if:

  • you do not want to depend on the generated method name;
  • you need a generic call by string identifier;
  • you are building your own wrappers on top of Workspace or WorkspaceClient.

If you need to run a request against an arbitrary absolute URL that is not described in Workspace at all, use the method named after the HTTP verb, for example Get, Post, Put, Patch, Delete, Head, Options.

Example call to an arbitrary URL:

[SerializeField] private Workspace workspace;

Post result = await workspace.Get<Post>("https://jsonplaceholder.typicode.com/posts/1");

In this mode, the request runs as a normal HTTP call against an already prepared URL. This is useful for temporary integrations, external services, debug calls, and other cases where you do not want to define the endpoint in Workspace first.

Why It Is Better to Use the Generated Client

The generated client simplifies day-to-day API work and makes integrations more stable.

1. Less Manual Code

You do not have to manually build URLs, parameters, request sending, and response parsing every time. This reduces boilerplate and frees time for product logic.

2. Fewer Integration Errors

When the API is described in Workspace and the client is generated automatically, the number of common mistakes goes down:

  • typos in paths;
  • forgotten parameters, headers, or cookies;
  • wrong HTTP methods;
  • different parameter passing formats in different parts of the project;
  • accidental differences in how the same endpoint is called in two places;
  • usage of deprecated endpoints that are no longer supported by the API.

The risk of mistakes is moved from manual integration into centralized configuration, which is easier to review and maintain.

3. Typed Methods and Models

If schemas are configured, the client works with C# types instead of raw JSON.

  • method signatures are easier to understand;
  • the IDE gives better suggestions for parameters and return values;
  • there is less manual parsing and fewer parsing-related mistakes;
  • code that uses the API is easier to read and refactor.

A typed call is almost always clearer and safer than a string-based request with manual deserialization.

4. Easier Maintenance and Evolution

If the API changes, it is usually enough to:

  1. Update the Workspace or re-import OpenAPI / Swagger.
  2. Regenerate the client.
  3. Fix the places in code where signatures actually changed.

This flow is faster and more reliable than manually searching for every request across the project. It also establishes a shared team standard and makes reviews easier.

11. Error Handling and Request Tracking

At runtime there are two main error-handling scenarios:

  1. You call Workspace.Execute(...), WorkspaceClient.Execute(...), or the generated client in exception mode.
  2. The generated client is configured to return a default value without throwing an exception.

If you want to properly handle application errors, server responses, and network failures in code, the main option is to catch WorkspaceClientException.

Example:

try
{
    UserProfile response = await workspace.Execute<UserProfile>("users.profile");
    Debug.Log(response.name);
}
catch (WorkspaceClientException exception)
{
    ExecutionResult result = exception.Result;

    Debug.Log("Status: " + result.statusCode);
    Debug.Log("Error Type: " + result.errorType);
    Debug.Log("Message: " + result.errorMessage);
    Debug.Log("Body: " + result.responseBody);
}

What is important to inspect in WorkspaceClientException.Result:

  • statusCode - the HTTP status code;
  • errorType - the error classification;
  • errorMessage - a short message describing the reason;
  • responseBody - the response body from the server, if one was returned;
  • responseHeaders - the response headers;
  • responseCookies - the response cookies;
  • isRetryable - whether it is safe to retry the request;
  • durationMs - how long the request took;
  • requestPreview - the final request after URL, path/query parameters, headers, and body are resolved.

The errorType field helps you quickly understand the kind of problem:

  • Auth - an authorization or authentication issue, usually 401 or 403;
  • Http4xx - a client-side error, for example invalid parameters, an invalid body, 404, 409, 422;
  • RateLimited - the server limited requests, usually 429;
  • Http5xx - a server error;
  • Timeout - the request timed out;
  • Transport - a network error before a normal HTTP response was received;
  • Serialization - the request could not be serialized or the response could not be deserialized;
  • Cancelled - the request was cancelled via CancellationToken.

In practice, handling often looks like this:

catch (WorkspaceClientException exception)
{
    ExecutionResult result = exception.Result;

    switch (result.errorType)
    {
        case ExecutionErrorType.Auth:
            ShowLoginExpired();
            break;
        case ExecutionErrorType.RateLimited:
            ShowTryAgainLater();
            break;
        case ExecutionErrorType.Http4xx:
            ShowValidationError(result.responseBody);
            break;
        case ExecutionErrorType.Http5xx:
        case ExecutionErrorType.Timeout:
        case ExecutionErrorType.Transport:
            ShowConnectionProblem();
            break;
        default:
            ShowUnknownError(result.errorMessage);
            break;
    }
}

How to understand what the server actually returned:

  1. First check statusCode.
  2. Then inspect responseBody.
  3. If the server returns JSON with an error model, deserialize responseBody into your own error DTO.
  4. If you need more context, inspect responseHeaders.

Example of parsing a server error:

catch (WorkspaceClientException exception)
{
    ExecutionResult result = exception.Result;
    SilkJson.Json error = SilkJson.Json.Parse(result.responseBody);

    Debug.Log("API error code: " + error["code"]);
    Debug.Log("API error message: " + error["message"]);
}

If you do not want exceptions and prefer manual control through the execution result, use overloads that return ExecutionResult:

ExecutionResult result = await workspace.Execute("users.profile");
if (!result.success)
{
    Debug.Log(result.errorType);
    Debug.Log(result.responseBody);
    return;
}

This is useful when you want centralized error handling without try/catch, for example inside your own networking wrapper.

It is also important to understand how the generated client behaves:

  • if Generation / Request Errors is set to ThrowException, generated methods behave like normal runtime calls and throw WorkspaceClientException;
  • if it is set to ReturnDefault, generated methods catch WorkspaceClientException, call RequestErrorHandlingUtility.Handle(...), and return default.

In the second mode, the error does not escape, so:

  • for Task<T> you get null, 0, false, or another default value;
  • for Task the method simply completes without a result;
  • logging in the Unity Console depends on Settings / Request Errors;
  • if Settings / Request Errors is set to Ignore, the error may be completely suppressed.

If you do not want to lose runtime errors, it is usually safer in production code to use ThrowException or direct Workspace.Execute(...) / WorkspaceClient.Execute(...) calls with your own try/catch.

What is included in the WorkspaceClientException text:

  • errorMessage;
  • the endpoint Id or Alias, if the request was executed through an endpoint;
  • a masked URL, if the endpoint is not defined;
  • path parameters;
  • query parameters.

If Settings / Mask Secrets In URLs is enabled, secret values in URLs and sensitive query parameters will be hidden in error messages and history.

For more complex cases, it is convenient to combine runtime and editor debugging:

  1. Catch WorkspaceClientException and save statusCode, errorType, and responseBody.
  2. Repeat the same endpoint in the Request or Test tab.
  3. Compare the final URL, headers, body, and server response.
  4. If needed, enable runtime request history and inspect the History tab.

Updating Asset

We send to Unity Asset Store only stable versions.

Ultimate Editor Enhancer has a built-in update system, using which you can download the latest versions of Internet Data Framework and get early access to all versions and updates.

Important: Always back up the project before updating assets.

Select "Tools / Internet Data Framework / Check Updates", to open the updater window.
Enter your Invoice Number or Order Number, select the update channel and click "Check New Versions".

You can find your Invoice Number in Unity Asset Store order confirmation email, or on the orders page in Unity Asset Store:
https://assetstore.unity.com/orders

If more than 10 updates were released in the selected channel from the current version, only the last 10 updates will be shown.

If updates are available, you can read the list of changes and download the update.

If you have problems installing the update, then:

  1. Remove "Plugins / Internet Data Framework" folder.

  2. Import the new version of Internet Data Framework into the project.

If you want to return to the previous version of Internet Data Framework, then select the channel "Stable Previous". Using this channel, you can get 10 previous stable versions.

Internet Data Framework automatically checks for updates every 24 hours. If the new version is available, you will see an icon in the Actions. Clicking on this action will open the updater window.

Automatic update check does not require an Invoice Number, and works on a previously selected update channel. If you did not select the update channel, then only stable versions will be checked.

Final words

We sincerely hope that you enjoy using Ultimate Editor Enhancer.
If you have any questions or problems, please contact us.
We will try to help you as quickly as possible.

Please don't forget to leave a review on the store page if you liked Internet Data Framework, this helps us a lot!
It is very important for us to have feedback to make our assets better.

Product page: https://infinity-code.com/assets/internet-data-framework
Asset Store: https://assetstore.unity.com/packages/slug/369228
Discord: https://discord.gg/2XRWwPgZK4
Support: support@infinity-code.com
Forum: https://forum.infinity-code.com
YouTube: https://www.youtube.com/channel/UCxCID3jp7RXKGqiCGpjPuOg