diff --git a/CHANGELOG.md b/CHANGELOG.md
index dfb9f00..d6050f7 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -5,6 +5,26 @@ All notable changes to the Apify Java client are documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project
adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
+## [0.11.0] - 2026-10-26
+
+### Added
+
+- `Build.getActorDefinition()` and the `ActorDefinition`, `ActorDefinitionMeta` and
+ `ActorDefinitionStorages` models for the build's `actorDefinition`, including the new `title`,
+ `description`, `output`, `meta`, `storages.datasets`, `storages.keyValueStore`,
+ `webServerSchema` and `webServerMcpPath` fields.
+
+### Fixed
+
+- An explicit JSON `null` for a raw-JSON (`JsonNode`) model field, such as `Task.getInput()`, is now
+ returned as Java `null` instead of a `NullNode`.
+
+### Changed
+
+- Updated to Apify OpenAPI specification `v2-2026-10-26T112451Z`.
+- Documented that only runs with status `SUCCEEDED`, `FAILED`, `ABORTED` or `TIMED-OUT` can be
+ resurrected with `RunClient.resurrect`.
+
## [0.10.0] - 2026-10-21
### Added
diff --git a/README.md b/README.md
index c272636..b3b3f8a 100644
--- a/README.md
+++ b/README.md
@@ -23,7 +23,7 @@ Maven (Maven Central is a default repository, so no extra configuration is neede
com.apify
apify-client
- 0.10.0
+ 0.11.0
```
@@ -35,7 +35,7 @@ repositories {
}
dependencies {
- implementation 'com.apify:apify-client:0.10.0'
+ implementation 'com.apify:apify-client:0.11.0'
}
```
@@ -317,10 +317,10 @@ try {
The public `com.apify.client.Version` class (`import com.apify.client.Version;`) exposes two
constants:
-- `Version.CLIENT_VERSION` — the semantic version of this client (`0.10.0`).
+- `Version.CLIENT_VERSION` — the semantic version of this client (`0.11.0`).
- `Version.API_SPEC_VERSION` — the version of the [Apify OpenAPI specification](https://docs.apify.com/api/openapi.json)
(its `info.version` field) that this client's endpoints, parameters and models were last generated
- and checked against (`v2-2026-10-20T121847Z`). It is a snapshot, not a live compatibility
+ and checked against (`v2-2026-10-26T112451Z`). It is a snapshot, not a live compatibility
guarantee: the client keeps working against newer, backward-compatible spec revisions, but a
feature added to the API after this snapshot has no corresponding method here yet.
diff --git a/docs/README.md b/docs/README.md
index 04ad78f..92fa938 100644
--- a/docs/README.md
+++ b/docs/README.md
@@ -41,7 +41,7 @@ option types, so import each resource you use from its own package:
| `com.apify.client` (root) | `ApifyClient`, `ApifyClientBuilder`, `Version`, `PaginationList`, `ListOptions`, `StorageListOptions`, `ApifyResource` |
| `com.apify.client.http` | `ApifyClientException`, `ApifyApiException`, `ApifyTransportException`, `HttpTransport`, `DefaultHttpTransport`, `HttpTimeoutException` |
| `com.apify.client.actor` | `Actor`, `ActorClient`, `ActorCollectionClient`, `ActorListOptions`, `ActorStartOptions`, `ActorCallOptions`, `ActorBuildOptions`, `ActorStandby`, `ActorVersion`, `SourceCodeFile`, `ActorVersionClient`, `ActorVersionCollectionClient`, `ActorEnvVar`, `ActorEnvVarClient`, `ActorEnvVarCollectionClient`, `ValidateInputOptions`, `ActorStats`, `ActorDefaultRunOptions` |
-| `com.apify.client.build` | `Build`, `BuildClient`, `BuildCollectionClient`, `BuildActVersion`, `BuildMeta`, `BuildStats`, `BuildOptions`, `BuildUsage` |
+| `com.apify.client.build` | `Build`, `BuildClient`, `BuildCollectionClient`, `BuildActVersion`, `ActorDefinition`, `ActorDefinitionMeta`, `ActorDefinitionStorages`, `BuildMeta`, `BuildStats`, `BuildOptions`, `BuildUsage` |
| `com.apify.client.run` | `ActorRun`, `ActorRunStats`, `ActorRunOptions`, `ActorRunMeta`, `ActorRunUsage`, `RunClient`, `RunCollectionClient`, `RunListOptions`, `LastRunOptions`, `MetamorphOptions`, `RunChargeOptions`, `RunResurrectOptions`, `SetStatusMessageOptions` |
| `com.apify.client.dataset` | `Dataset`, `DatasetClient`, `DatasetCollectionClient`, `DatasetListItemsOptions`, `DatasetDownloadOptions`, `DownloadItemsFormat` |
| `com.apify.client.keyvalue` | `KeyValueStore`, `KeyValueStoreClient`, `KeyValueStoreCollectionClient`, `KeyValueStoreRecord`, `KeyValueStoreKeysPage`, `KeyValueStoreKey`, `GetRecordOptions`, `SetRecordOptions`, `ListKeysOptions` |
diff --git a/docs/builds.md b/docs/builds.md
index b1f5d8c..7255e2e 100644
--- a/docs/builds.md
+++ b/docs/builds.md
@@ -25,7 +25,14 @@ builds) and a single build with `client.build(id)`.
`Build` fields: `getId()`, `getActId()`, `getUserId()`, `getStatus()`, `getStartedAt()`,
`getFinishedAt()`, `getBuildNumber()`, `getActVersion()` (`BuildActVersion` — `getSourceType()`, `getBuildTag()`
(nullable), `getVersionNumber()`, `getGitRepoUrl()`, `getSourceFiles()` (`List` — `getName()`,
-`getFormat()`, `getContent()`)), `getImageDigest()` (`String`, nullable — the built Docker
+`getFormat()`, `getContent()`)), `getActorDefinition()` (`ActorDefinition`, nullable — the Actor's `.actor/actor.json` at build time:
+`getActorSpecification()`, `getName()`, `getTitle()`, `getDescription()`, `getVersion()`, `getBuildTag()`,
+`getMeta()` (`ActorDefinitionMeta` — `getTemplateId()`, `getGeneratedBy()`), `getEnvironmentVariables()`,
+`getDockerfile()`, `getDockerContextDir()`, `getReadme()`, `getInput()`/`getOutput()` (`JsonNode` schemas),
+`getChangelog()`, `getStorages()` (`ActorDefinitionStorages` — `getDataset()`, `getDatasets()`,
+`getKeyValueStore()`), `getDefaultMemoryMbytes()` (`JsonNode`, an integer or a dynamic memory
+expression), `getMinMemoryMbytes()`, `getMaxMemoryMbytes()`, `getUsesStandbyMode()`, `getWebServerSchema()`,
+`getWebServerMcpPath()`), `getImageDigest()` (`String`, nullable — the built Docker
image manifest's digest, without the `sha256:` prefix; compare two builds' digests to tell whether
their image contents differ), `getMeta()` (`BuildMeta` — `getOrigin()`, `getClientIp()`,
`getUserAgent()`), `getStats()` (`BuildStats` — `getDurationMillis()`/`getRunTimeSecs()` as `Long`,
@@ -34,7 +41,7 @@ their image contents differ), `getMeta()` (`BuildMeta` — `getOrigin()`, `getCl
`getUsage()` / `getUsageUsd()` (`BuildUsage` — `getActorComputeUnits()` as `Double`, the latter as
its USD cost), `getUsageTotalUsd()` (`Double`), plus `isTerminal()` and `getExtra()`. The status is
one of `READY`, `RUNNING`, `SUCCEEDED`, `FAILED`, `TIMING-OUT`, `TIMED-OUT`, `ABORTING`, `ABORTED`.
-Every nested model above (`BuildActVersion`, `BuildMeta`, `BuildStats`, `BuildOptions`, `BuildUsage`) also has its own
+Every nested model above (`BuildActVersion`, `ActorDefinition`, `ActorDefinitionMeta`, `ActorDefinitionStorages`, `BuildMeta`, `BuildStats`, `BuildOptions`, `BuildUsage`) also has its own
`getExtra()`, so a field not yet listed here is still reachable rather than dropped.
```java
diff --git a/docs/runs.md b/docs/runs.md
index 2668b71..c19d478 100644
--- a/docs/runs.md
+++ b/docs/runs.md
@@ -35,7 +35,7 @@ PaginationList runs = client.runs().list(
| `abort(Boolean gracefully)` | Abort the run (`null` = server default). Completes with `ActorRun`. |
| `metamorph(String targetActorId, Object input, MetamorphOptions)` | Metamorph into another Actor. Completes with `ActorRun`. |
| `reboot()` | Reboot the run. Completes with `ActorRun`. |
-| `resurrect(RunResurrectOptions)` | Resurrect a finished run. Completes with `ActorRun`. |
+| `resurrect(RunResurrectOptions)` | Resurrect a finished run (status `SUCCEEDED`, `FAILED`, `ABORTED` or `TIMED-OUT`). Completes with `ActorRun`. |
| `charge(RunChargeOptions)` | Charge a pay-per-event run for a named event. Completes with no value (`CompletableFuture`). |
| `waitForFinish(Long waitSecs)` | Poll until the run finishes (`null` waits indefinitely). Completes with `ActorRun`. |
| `dataset()` / `keyValueStore()` / `requestQueue()` | Clients for the run's default storages. |
diff --git a/pom.xml b/pom.xml
index e189322..fbe46db 100644
--- a/pom.xml
+++ b/pom.xml
@@ -6,7 +6,7 @@
com.apify
apify-client
- 0.10.0
+ 0.11.0
jar
Apify Java Client
diff --git a/spotbugs-exclude.xml b/spotbugs-exclude.xml
index cfafadb..39df467 100644
--- a/spotbugs-exclude.xml
+++ b/spotbugs-exclude.xml
@@ -19,6 +19,7 @@
2. UWF_UNWRITTEN_FIELD / UWF_UNWRITTEN_PUBLIC_OR_PROTECTED_FIELD on Jackson-populated DTOs/response
shapes ({@code KeyValueStoreKey}, {@code DeletedRequestInfo}, {@code ActorRunMeta}, {@code
TaskOptions}, {@code WebhookLastDispatch}, {@code ActorDefaultRunOptions}, {@code BuildActVersion},
+ {@code ActorDefinitionMeta}, {@code ActorDefinitionStorages},
{@code BuildMeta}, {@code BuildOptions}, {@code BuildStats}, {@code PricingInfo}, {@code ProxyGroup}, {@code
UserProxy}, {@code WebhookDispatchEventData}, {@code WebhookDispatchWebhookInfo}, the internal
error-response mapping in {@code HttpClientCore}): their fields are written by the
@@ -75,6 +76,8 @@
+
+
@@ -110,10 +113,19 @@
+
+
+
+
+
+
+
+
+
diff --git a/src/main/java/com/apify/client/Version.java b/src/main/java/com/apify/client/Version.java
index 95b44ba..638cb83 100644
--- a/src/main/java/com/apify/client/Version.java
+++ b/src/main/java/com/apify/client/Version.java
@@ -13,13 +13,13 @@ public final class Version {
* The semantic version of this client library (see SemVer).
* Changes to the public interface other than additive ones are considered breaking changes.
*/
- public static final String CLIENT_VERSION = "0.10.0";
+ public static final String CLIENT_VERSION = "0.11.0";
/**
* The version of the Apify OpenAPI specification this client was generated and verified against.
* Corresponds to the {@code info.version} field of the Apify OpenAPI document.
*/
- public static final String API_SPEC_VERSION = "v2-2026-10-20T121847Z";
+ public static final String API_SPEC_VERSION = "v2-2026-10-26T112451Z";
private Version() {}
}
diff --git a/src/main/java/com/apify/client/build/ActorDefinition.java b/src/main/java/com/apify/client/build/ActorDefinition.java
new file mode 100644
index 0000000..b96ea02
--- /dev/null
+++ b/src/main/java/com/apify/client/build/ActorDefinition.java
@@ -0,0 +1,148 @@
+package com.apify.client.build;
+
+import com.apify.client.ApifyResource;
+import java.util.Collections;
+import java.util.Map;
+import tools.jackson.databind.JsonNode;
+
+/**
+ * The definition of an Actor, as stored in its {@code .actor/actor.json}, from {@link
+ * Build#getActorDefinition()}. Every field is optional.
+ */
+public final class ActorDefinition extends ApifyResource {
+ private Integer actorSpecification;
+ private String name;
+ private String title;
+ private String description;
+ private String version;
+ private String buildTag;
+ private ActorDefinitionMeta meta;
+ private Map environmentVariables;
+ private String dockerfile;
+ private String dockerContextDir;
+ private String readme;
+ private JsonNode input;
+ private JsonNode output;
+ private String changelog;
+ private ActorDefinitionStorages storages;
+ private JsonNode defaultMemoryMbytes;
+ private Long minMemoryMbytes;
+ private Long maxMemoryMbytes;
+ private Boolean usesStandbyMode;
+ private JsonNode webServerSchema;
+ private String webServerMcpPath;
+
+ /** The Actor specification version that this Actor follows; always {@code 1}. */
+ public Integer getActorSpecification() {
+ return actorSpecification;
+ }
+
+ /** The name of the Actor. */
+ public String getName() {
+ return name;
+ }
+
+ /** The human-readable display title of the Actor, shown in Apify Console and Apify Store. */
+ public String getTitle() {
+ return title;
+ }
+
+ /** The description of the Actor. */
+ public String getDescription() {
+ return description;
+ }
+
+ /** The version of the Actor, a dot-separated sequence of numbers (e.g. {@code "0.1"}). */
+ public String getVersion() {
+ return version;
+ }
+
+ /** The tag applied to a successful build of the Actor; {@code latest} when not specified. */
+ public String getBuildTag() {
+ return buildTag;
+ }
+
+ /** Additional information about the Actor. */
+ public ActorDefinitionMeta getMeta() {
+ return meta;
+ }
+
+ /**
+ * Environment variables used during local development and deployment; an empty map when none are
+ * defined.
+ */
+ public Map getEnvironmentVariables() {
+ return environmentVariables == null
+ ? Map.of()
+ : Collections.unmodifiableMap(environmentVariables);
+ }
+
+ /** The path to the Dockerfile used for building the Actor on the platform. */
+ public String getDockerfile() {
+ return dockerfile;
+ }
+
+ /** The path to the directory used as the Docker context when building the Actor. */
+ public String getDockerContextDir() {
+ return dockerContextDir;
+ }
+
+ /** The path to the README file for the Actor; {@code null} if there is none. */
+ public String getReadme() {
+ return readme;
+ }
+
+ /** The input schema object; {@code null} if the Actor has no input schema. */
+ public JsonNode getInput() {
+ return input;
+ }
+
+ /** The output schema object; {@code null} if the Actor has no output schema. */
+ public JsonNode getOutput() {
+ return output;
+ }
+
+ /** The path to the CHANGELOG file shown in the Actor's information tab; may be {@code null}. */
+ public String getChangelog() {
+ return changelog;
+ }
+
+ /** The schemas of the Actor's storages. */
+ public ActorDefinitionStorages getStorages() {
+ return storages;
+ }
+
+ /**
+ * The default memory in megabytes used when the Actor is started: either a JSON integer or a
+ * string with a dynamic memory expression (e.g. {@code "get(input, 'startUrls.length', 1) *
+ * 1024"}).
+ */
+ public JsonNode getDefaultMemoryMbytes() {
+ return defaultMemoryMbytes;
+ }
+
+ /** The minimum memory in megabytes required by the Actor. */
+ public Long getMinMemoryMbytes() {
+ return minMemoryMbytes;
+ }
+
+ /** The maximum memory in megabytes required by the Actor. */
+ public Long getMaxMemoryMbytes() {
+ return maxMemoryMbytes;
+ }
+
+ /** Whether Standby mode is enabled for the Actor. */
+ public Boolean getUsesStandbyMode() {
+ return usesStandbyMode;
+ }
+
+ /** The OpenAPI v3 specification of the web server running in the Actor. */
+ public JsonNode getWebServerSchema() {
+ return webServerSchema;
+ }
+
+ /** The HTTP path where the Actor's web server exposes its MCP server (e.g. {@code "/mcp"}). */
+ public String getWebServerMcpPath() {
+ return webServerMcpPath;
+ }
+}
diff --git a/src/main/java/com/apify/client/build/ActorDefinitionMeta.java b/src/main/java/com/apify/client/build/ActorDefinitionMeta.java
new file mode 100644
index 0000000..49a8f12
--- /dev/null
+++ b/src/main/java/com/apify/client/build/ActorDefinitionMeta.java
@@ -0,0 +1,19 @@
+package com.apify.client.build;
+
+import com.apify.client.ApifyResource;
+
+/** Additional information about an Actor, from {@link ActorDefinition#getMeta()}. */
+public final class ActorDefinitionMeta extends ApifyResource {
+ private String templateId;
+ private String generatedBy;
+
+ /** The ID of the template from which the Actor was created. */
+ public String getTemplateId() {
+ return templateId;
+ }
+
+ /** The tool or model that generated the Actor. */
+ public String getGeneratedBy() {
+ return generatedBy;
+ }
+}
diff --git a/src/main/java/com/apify/client/build/ActorDefinitionStorages.java b/src/main/java/com/apify/client/build/ActorDefinitionStorages.java
new file mode 100644
index 0000000..70656dc
--- /dev/null
+++ b/src/main/java/com/apify/client/build/ActorDefinitionStorages.java
@@ -0,0 +1,34 @@
+package com.apify.client.build;
+
+import com.apify.client.ApifyResource;
+import java.util.Collections;
+import java.util.Map;
+import tools.jackson.databind.JsonNode;
+
+/** The storage schemas of an Actor, from {@link ActorDefinition#getStorages()}. */
+public final class ActorDefinitionStorages extends ApifyResource {
+ private JsonNode dataset;
+ private Map datasets;
+ private JsonNode keyValueStore;
+
+ /**
+ * The schema of the items in the Actor's dataset, as defined in the Actor's {@code
+ * .actor/actor.json}.
+ */
+ public JsonNode getDataset() {
+ return dataset;
+ }
+
+ /**
+ * Maps dataset aliases to the schemas of the Actor's datasets; an empty map when the Actor
+ * defines none.
+ */
+ public Map getDatasets() {
+ return datasets == null ? Map.of() : Collections.unmodifiableMap(datasets);
+ }
+
+ /** The schema of the Actor's default key-value store. */
+ public JsonNode getKeyValueStore() {
+ return keyValueStore;
+ }
+}
diff --git a/src/main/java/com/apify/client/build/Build.java b/src/main/java/com/apify/client/build/Build.java
index 7a01932..38b159f 100644
--- a/src/main/java/com/apify/client/build/Build.java
+++ b/src/main/java/com/apify/client/build/Build.java
@@ -15,6 +15,7 @@ public final class Build extends ApifyResource {
private String buildNumber;
private String imageDigest;
private BuildActVersion actVersion;
+ private ActorDefinition actorDefinition;
private BuildMeta meta;
private BuildStats stats;
private BuildOptions options;
@@ -78,6 +79,14 @@ public BuildActVersion getActVersion() {
return actVersion;
}
+ /**
+ * The definition of the Actor this build was created from, as stored in its {@code
+ * .actor/actor.json}. {@code null} if the build has none.
+ */
+ public ActorDefinition getActorDefinition() {
+ return actorDefinition;
+ }
+
/** Metadata about how the build was initiated. */
public BuildMeta getMeta() {
return meta;
diff --git a/src/main/java/com/apify/client/internal/Json.java b/src/main/java/com/apify/client/internal/Json.java
index 2933554..f1d1096 100644
--- a/src/main/java/com/apify/client/internal/Json.java
+++ b/src/main/java/com/apify/client/internal/Json.java
@@ -2,10 +2,13 @@
import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.JsonInclude;
+import com.fasterxml.jackson.annotation.JsonSetter;
+import com.fasterxml.jackson.annotation.Nulls;
import tools.jackson.core.JacksonException;
import tools.jackson.core.type.TypeReference;
import tools.jackson.databind.DeserializationFeature;
import tools.jackson.databind.JavaType;
+import tools.jackson.databind.JsonNode;
import tools.jackson.databind.ObjectMapper;
import tools.jackson.databind.cfg.DateTimeFeature;
import tools.jackson.databind.json.JsonMapper;
@@ -37,6 +40,12 @@ public final class Json {
// live API instead of every such field having to be widened to a boxed type.
.configure(DeserializationFeature.FAIL_ON_NULL_FOR_PRIMITIVES, false)
.configure(DateTimeFeature.WRITE_DATES_AS_TIMESTAMPS, false)
+ // Jackson materializes an explicit JSON null for a JsonNode field as a NullNode, which
+ // is not a Java null. Models document nullable raw-JSON fields as returning null, so a
+ // null value is skipped and the field keeps its default of null.
+ .withConfigOverride(
+ JsonNode.class,
+ override -> override.setNullHandling(JsonSetter.Value.forValueNulls(Nulls.SKIP)))
.changeDefaultPropertyInclusion(
incl -> incl.withValueInclusion(JsonInclude.Include.NON_NULL))
// Bind directly to (private) fields so models need no setters — getters remain the
diff --git a/src/main/java/com/apify/client/run/RunClient.java b/src/main/java/com/apify/client/run/RunClient.java
index 3bf64a5..2236931 100644
--- a/src/main/java/com/apify/client/run/RunClient.java
+++ b/src/main/java/com/apify/client/run/RunClient.java
@@ -142,7 +142,10 @@ public CompletableFuture reboot() {
return ctx.postWithBody("reboot", new QueryParams(), null, "", ActorRun.class);
}
- /** Resurrects a finished run, starting it again from the beginning. */
+ /**
+ * Resurrects a finished run, starting it again from the beginning. Only runs with status {@code
+ * SUCCEEDED}, {@code FAILED}, {@code ABORTED} or {@code TIMED-OUT} can be resurrected.
+ */
public CompletableFuture resurrect(RunResurrectOptions options) {
if (options == null) {
throw new IllegalArgumentException("options is required and must not be null");
diff --git a/src/test/java/com/apify/client/NestedDtoForwardCompatTest.java b/src/test/java/com/apify/client/NestedDtoForwardCompatTest.java
index 64278e2..bc56e16 100644
--- a/src/test/java/com/apify/client/NestedDtoForwardCompatTest.java
+++ b/src/test/java/com/apify/client/NestedDtoForwardCompatTest.java
@@ -5,6 +5,7 @@
import static org.junit.jupiter.api.Assertions.assertTrue;
import com.apify.client.actor.ActorStandby;
+import com.apify.client.build.ActorDefinition;
import com.apify.client.build.Build;
import com.apify.client.build.BuildStats;
import com.apify.client.internal.Json;
@@ -14,6 +15,7 @@
import com.apify.client.run.ActorRunStats;
import com.apify.client.schedule.ScheduleNotifications;
import com.apify.client.store.PricingInfo;
+import com.apify.client.task.Task;
import com.apify.client.task.TaskStats;
import com.apify.client.user.UserProfile;
import com.apify.client.webhook.Webhook;
@@ -104,6 +106,67 @@ void buildActVersionAcceptsNullBuildTag() {
assertEquals("SOURCE_FILES", untagged.getActVersion().getSourceType());
}
+ @Test
+ void buildActorDefinitionModelsAllFieldsAndAcceptsNull() {
+ Build build =
+ parse(
+ "{\"id\":\"b1\",\"actorDefinition\":{\"actorSpecification\":1,\"name\":\"my-actor\","
+ + "\"title\":\"My Actor\",\"description\":\"Does things\",\"version\":\"0.1\","
+ + "\"buildTag\":\"latest\",\"meta\":{\"templateId\":\"js-start\","
+ + "\"generatedBy\":\"Claude\"},\"environmentVariables\":{\"A\":\"b\"},"
+ + "\"dockerfile\":\"./Dockerfile\",\"dockerContextDir\":\"..\","
+ + "\"readme\":\"./README.md\",\"input\":{\"type\":\"object\"},"
+ + "\"output\":{\"actorOutputSchemaVersion\":1},\"changelog\":null,"
+ + "\"storages\":{\"dataset\":{\"views\":{}},\"datasets\":{\"extra\":{\"views\":{}}},"
+ + "\"keyValueStore\":{\"actorKeyValueStoreSchemaVersion\":1}},"
+ + "\"defaultMemoryMbytes\":\"get(input, 'n', 1) * 1024\",\"minMemoryMbytes\":128,"
+ + "\"maxMemoryMbytes\":4096,\"usesStandbyMode\":true,"
+ + "\"webServerSchema\":{\"openapi\":\"3.0.0\"},\"webServerMcpPath\":\"/mcp\","
+ + "\"someFutureField\":1}}",
+ Build.class);
+
+ ActorDefinition def = build.getActorDefinition();
+ assertEquals(1, def.getActorSpecification().intValue());
+ assertEquals("my-actor", def.getName());
+ assertEquals("My Actor", def.getTitle());
+ assertEquals("Does things", def.getDescription());
+ assertEquals("0.1", def.getVersion());
+ assertEquals("latest", def.getBuildTag());
+ assertEquals("js-start", def.getMeta().getTemplateId());
+ assertEquals("Claude", def.getMeta().getGeneratedBy());
+ assertEquals("b", def.getEnvironmentVariables().get("A"));
+ assertEquals("./Dockerfile", def.getDockerfile());
+ assertEquals("..", def.getDockerContextDir());
+ assertEquals("./README.md", def.getReadme());
+ assertEquals("object", def.getInput().get("type").asString());
+ assertEquals(1, def.getOutput().get("actorOutputSchemaVersion").asInt());
+ assertNull(def.getChangelog());
+ assertTrue(def.getStorages().getDataset().has("views"));
+ assertTrue(def.getStorages().getDatasets().get("extra").has("views"));
+ assertEquals(
+ 1, def.getStorages().getKeyValueStore().get("actorKeyValueStoreSchemaVersion").asInt());
+ assertEquals("get(input, 'n', 1) * 1024", def.getDefaultMemoryMbytes().asString());
+ assertEquals(128L, def.getMinMemoryMbytes().longValue());
+ assertEquals(4096L, def.getMaxMemoryMbytes().longValue());
+ assertEquals(true, def.getUsesStandbyMode());
+ assertEquals("3.0.0", def.getWebServerSchema().get("openapi").asString());
+ assertEquals("/mcp", def.getWebServerMcpPath());
+ assertEquals(1, def.getExtra().get("someFutureField"));
+
+ ActorDefinition empty =
+ parse("{\"id\":\"b2\",\"actorDefinition\":{}}", Build.class).getActorDefinition();
+ assertTrue(empty.getEnvironmentVariables().isEmpty());
+ assertNull(empty.getStorages());
+ ActorDefinition nulls =
+ parse("{\"id\":\"b5\",\"actorDefinition\":{\"input\":null,\"output\":null}}", Build.class)
+ .getActorDefinition();
+ assertNull(nulls.getInput());
+ assertNull(nulls.getOutput());
+ assertNull(parse("{\"id\":\"t1\",\"input\":null}", Task.class).getInput());
+ assertNull(parse("{\"id\":\"b3\",\"actorDefinition\":null}", Build.class).getActorDefinition());
+ assertNull(parse("{\"id\":\"b4\"}", Build.class).getActorDefinition());
+ }
+
@Test
void webhookModelsAdHocFlagAndCondition() {
Webhook adHoc =
diff --git a/src/test/java/com/apify/client/integration/BuildIntegrationTest.java b/src/test/java/com/apify/client/integration/BuildIntegrationTest.java
index 88502c9..fc41888 100644
--- a/src/test/java/com/apify/client/integration/BuildIntegrationTest.java
+++ b/src/test/java/com/apify/client/integration/BuildIntegrationTest.java
@@ -7,6 +7,7 @@
import com.apify.client.ListOptions;
import com.apify.client.actor.Actor;
import com.apify.client.actor.ActorBuildOptions;
+import com.apify.client.build.ActorDefinition;
import com.apify.client.build.Build;
import com.apify.client.build.BuildClient;
import org.junit.jupiter.api.Test;
@@ -20,6 +21,16 @@ void listBuilds() {
assertTrue(page.getTotal() >= 0);
}
+ @Test
+ void storeActorBuildCarriesActorDefinition() {
+ ApifyClient client = requireClient();
+ Build build =
+ client.actor("apify/hello-world").defaultBuild(60L).join().get().join().orElseThrow();
+ ActorDefinition definition = build.getActorDefinition();
+ assertNotNull(definition, "the default build of a store Actor carries its actorDefinition");
+ assertNotNull(definition.getInput(), "hello-world declares an input schema");
+ }
+
@Test
void buildActorFlow() {
ApifyClient client = requireClient();