LibraryHiggsfield Integrationv5 · Updated Report

Higgsfield Integration

Integration Identityhiggsfield · media generation
Category
media generation
Provider
Higgsfield
Namespace
higgsfield

Estimate, submit, poll, and cancel Higgsfield media generation requests through a connected Higgsfield API key, and hand every output the user wants to keep to Files before its temporary URL expires.

Integration Capability8
AccessMethodSide EffectDescription
readlistSourcesNo

Discover connected Higgsfield keys. Every provider-backed higgsfield.* call takes one of these sourceIds, and each row carries the capabilityTierId that decides whether generation is possible at all. Returns an envelope with a sources array and an optional nextCursor, not a bare array.

readlistModelsNo

List the two model contracts this connector supports, Soul Standard text-to-image and DoP Standard image-to-video. Answered locally, so it needs no sourceId, reaches no provider, and spends no call budget.

readestimateImageNo

Ask Higgsfield what one Soul Standard image request would cost right now. Both credits and usd come back as strings, never numbers; parse before you compare them.

readestimateVideoNo

Ask Higgsfield what one DoP Standard image-to-video request would cost right now, using the same imageUrl and prompt you intend to submit. Both credits and usd come back as strings.

writegenerateImageYes

Submit one Soul Standard text-to-image request. Receipted: requires a stable caller-generated UUIDv7 operationId and makes exactly one provider attempt. The result is a submission handle, requestId plus status, never media; media exists only after getRequestStatus reports completed.

writegenerateVideoYes

Submit one DoP Standard image-to-video request from an HTTPS source image that Higgsfield itself must be able to fetch. Receipted the same way as generateImage, one provider attempt per operationId, and the result is a submission handle rather than a video.

readgetRequestStatusNo

Read one request's live state. A completed result with media also carries a filesHandoff naming files.ingestFileFromUrl, the owning organizationId, and the exact durability procedure; a queued or failed result carries no handoff. The retentionNotice is present on every response, completed or not.

writecancelRequestYes

Ask Higgsfield to cancel one queued request. Receipted, and only an acknowledgement: cancellation is not terminal until getRequestStatus reports canceled. A request that has already started processing is refused, and that refusal is final rather than retryable.

Integration Source DiscoverylistSources · connected Higgsfield API key
Method
listSources
Source Kind
connected Higgsfield API key

Start here when you need a concrete connected key. Every provider-reaching call takes the returned sourceId, and the row tells you whether the key is active, unpaused, and provisioned for generation.

Limitations

The namespace exposes exactly two model contracts, higgsfield-ai/soul/standard and higgsfield-ai/dop/standard; no other Higgsfield model, no editing or upscaling endpoint, and no raw request escape hatch is reachable. There is no way to list your account's past or in-flight requests: a requestId exists only in the reply to your own submission, so an ambiguous submit leaves you with no local handle to reconcile against. Media bytes never move through this namespace, only URLs; downloading or base64-encoding an output is forbidden, and durability comes from the Files handoff alone. Provider response bodies are bounded and re-decoded, so provider control URLs, provider error text, and any extra fields on a media entry are dropped before the result reaches model context; only the url survives. A generate refusal at HTTP 400 is genuinely two-sided, either the input is wrong or the account already has active work, and the connector cannot tell you which. Cancellation is impossible once processing has started. An HTTP 401 terminalizes the credential for that call as authentication_rejected rather than being retried.

Usage

generateImage, generateVideo, and cancelRequest each take a caller-generated UUIDv7 operationId, carry a durable receipt, and make exactly one provider attempt. Generate the operationId on your own host before the first attempt and keep the literal; call ids.mintOperationIds only if your host cannot generate a UUIDv7, in a run of its own where it is the only provider call. A UUIDv4 is rejected by the parameter schema, not merely discouraged. Replaying a completed operationId returns the stored receipt with replayed true and makes no provider contact. An attempt whose outcome is unknown, meaning a transport failure or a provider 5xx, fails as ambiguous, and here the guidance is the opposite of a blind retry and also the opposite of minting a fresh id: reuse that same operationId, which will keep answering ambiguous without a second POST, and reconcile against Higgsfield itself before deciding anything. Poll getRequestStatus no sooner than two seconds after a submit and back off toward ten seconds; pace long waits across separate runs rather than spinning inside one. Each run has a budget of forty provider calls, and every estimate, generate, status, and cancel call spends one; listSources and listModels are answered locally and spend none. Outbound requests hold one of three shared permits, so a Promise.all fan-out queues rather than parallelizing. listSources pages through nextCursor with limit between one and fifty. Prompts are capped at ten thousand characters, numImages at four, seed between one and one million, and image URLs must be HTTPS.

Authorization

Two independent planes both have to allow a write. The connector capability tier decides what the key may do: read covers listing, estimates, and status reads, while full adds generation and cancellation, and a connection defaults to read unless it was created as full. The MCP token scope decides it again: without mcp:write the three writing methods reject with missing_write_scope while the five reads keep working, so a read-only token on a full-tier key still cannot generate. On top of both, every call resolves the source through live membership and refuses unless the owning organization is active; a quarantining, quarantined, deleting, tearing down, or deleted organization is fenced, and a quarantined organization's connections still appear in listSources with their lifecycleStatus, but every estimate, status read, generation and cancellation against them is refused until the organization is active again. The Higgsfield credential is a static API key held server-side, sent as an Authorization key header, and never present in model context. Reconnecting supersedes the row and mints a new sourceId, so a cached sourceId can fail as stale; the fix is always to call listSources again rather than to retry.

Composition

Higgsfield outputs become durable only through Files. A completed getRequestStatus hands you a filesHandoff carrying the owning organizationId and the exact procedure: generate one UUIDv7 creationId per output on your own host, or with ids.mintOperationIds in a run of its own when the host cannot, call files.ingestFileFromUrl with that creationId, the output URL, a filename, a MIME type, and a maxBytes refusal bound, then poll files.getFileIngestion until state is completed. The reverse direction works too: when the source image for generateVideo already lives in Files, files.getReadLink mints a signed HTTPS URL that Higgsfield can fetch, though it expires in about fifteen minutes, so submit promptly rather than minting it early in a long plan.

Higgsfield Integration

What it does

The Higgsfield integration lets an agent spend a connected Higgsfield API key deliberately: read what a request would cost, submit one generation with a durable receipt, poll it to a terminal state, cancel it while it is still queued, and move the finished output into Files before the provider's temporary URL expires. The callable namespace is higgsfield. Exactly two model contracts are reachable, Soul Standard for text-to-image and DoP Standard for image-to-video, and media bytes never pass through model context in either direction.

The shape of every workflow here is the same: a submission returns a handle, not a result. generateImage and generateVideo answer with a requestId and a status, and nothing else. Even if the provider happened to include media in its submission reply, the receipt keeps only the handle. Media appears exclusively in getRequestStatus.

Finding the connection and reading the tier

Start with higgsfield.listSources. It returns an envelope, { sources, nextCursor? }, and not a bare array; nextCursor is present only when another page exists, and limit accepts one to fifty. Each row identifies one connected key and carries four things worth checking before you commit to it: status, which is active or needs_reauth; paused, which is a boolean; organizationId with its lifecycleStatus; and capabilityTierId, which is read or full.

That last field is the one agents skip and then pay for. A read tier key can estimate and poll all day and will refuse every generation, so checking it costs nothing and saves you from burning a freshly minted operationId on a call that was never going to reach the provider. A paused source, a needs_reauth source, and a non-active organization are all refused at the access gate before any budget is spent.

Source ids are not stable across reconnects. Reconnecting supersedes the connection row and mints a new sourceId, and a call against the old one fails with a message telling you to list again. Treat listing as cheap and caching as a liability.

Estimating before you spend

estimateImage and estimateVideo ask Higgsfield what a specific request would cost right now, using the same fields you intend to submit. Give them the real prompt and the real options; an estimate for a different shape of request is not an estimate for yours.

Both return { credits, usd }, and both fields are strings. They are not numbers and they are not currency-formatted for display. Comparing them with < or summing them with + will silently do string work and produce a wrong answer that looks plausible, so parse first.

const { sources } = await higgsfield.listSources({})
const source = sources.find(s => s.status === 'active' && !s.paused && s.capabilityTierId === 'full')

const shape = { prompt: 'A paper moon over a quiet harbour', numImages: 2, aspectRatio: '16:9' }
const { credits, usd } = await higgsfield.estimateImage({ sourceId: source.sourceId, ...shape })
console.log(Number(usd)) // credits and usd are strings, not numbers

// operationId is a UUIDv7 generated on your own host and kept as a literal
const { replayed, request } = await higgsfield.generateImage({
  sourceId: source.sourceId,
  operationId: '019f2c8a-7b41-7c6e-9f2a-3d5b8e10a4c2',
  ...shape,
})
console.log(request.requestId, request.status) // queued; no media exists yet

The example shows the flow; live server validation inside run is authoritative for exact parameters.

Submitting: receipts, one attempt, and ambiguity

Every generation and every cancellation takes a caller-generated UUIDv7 operationId, carries a durable receipt, and reaches the provider exactly once. The version matters: the parameter schema accepts UUIDv7 only, so a UUIDv4 is rejected before the call runs. Generate the id on your own host before the first attempt and keep the literal; call ids.mintOperationIds only if your host cannot generate a UUIDv7, in a run of its own in which it is the only provider call, then carry the literal forward.

Calling again with an operationId that already succeeded returns the stored receipt with replayed: true and no provider contact, which makes an accidental repeat harmless.

Ambiguity is where this namespace departs from the pattern you may expect. A transport failure or a provider 5xx on a submit or a cancel produces an ambiguous outcome: the request may or may not have reached Higgsfield. The operationId is now spent, and calling it again returns the same ambiguous answer without issuing a second POST, which is exactly the protection you want. What you must not do is mint a fresh operationId and submit again, because that is how you pay twice for the same image. The instruction the error itself carries is to reuse the operationId and inspect provider state.

Be honest with yourself about what inspecting provider state means here. An ambiguous submit never handed you a requestId, and this namespace has no method that lists requests, so there is no in-band way to discover whether the work exists. Reconciliation has to happen against the Higgsfield account itself, by a person or by another channel, before anyone decides to spend again. Say so plainly to the user rather than resolving the uncertainty by guessing.

Polling to completion, then saving the output

getRequestStatus takes the sourceId and the requestId from the submission. Its status is one of queued, in_progress, nsfw, failed, completed, or canceled. Handle nsfw explicitly: it is a terminal content refusal, distinct from failed, and no amount of further polling will move it. Per the connector's own guidance, begin polling no sooner than two seconds after submitting and back off toward ten seconds. Long waits belong across separate runs, not inside a busy loop that eats the forty-call budget.

The response always carries a retentionNotice. It is not decoration: as the connector's own guidance states, Higgsfield guarantees an output URL for at least seven days only, and the URL is not durable until a Files ingestion of it completes. images and video are present only when the provider returned them, so a completed image request yields images while a completed video request yields video, and neither is present while the request is still queued.

When a request completes with media, the response also carries filesHandoff. That object is the instruction, not a hint. It names the method (files.ingestFileFromUrl), the status method (files.getFileIngestion), and the exact organizationId the file belongs in, and it carries the full procedure in its instructions string. Follow it: generate one UUIDv7 creationId per output on your own host, or with ids.mintOperationIds in a run of its own when the host cannot, then call files.ingestFileFromUrl from a run holding mcp:write with that creationId, the URL, a filename you choose, a MIME type you choose, and a maxBytes refusal bound you choose, and poll files.getFileIngestion until state is completed. Never fetch the URL yourself, never base64-encode the bytes, and never tell the user the media is saved before the ingestion state says completed. A queued or failed request carries no filesHandoff, and its absence on a completed response means there was no media to keep.

const status = await higgsfield.getRequestStatus({ sourceId, requestId })

if (status.status === 'nsfw' || status.status === 'failed' || status.status === 'canceled') {
  // terminal; do not keep polling
} else if (status.status === 'completed' && status.filesHandoff) {
  const handoff = status.filesHandoff
  // creationId is a UUIDv7 generated on your own host and kept as a literal
  const ingestion = await files.ingestFileFromUrl({
    organizationId: handoff.organizationId,
    creationId: '019f2c8b-1d02-7a55-8c31-6f0b9e42d7a1',
    url: status.images[0].url,
    filename: 'paper-moon.png',
    mimeType: 'image/png',
    maxBytes: 25_000_000,
  })
  // not durable until files.getFileIngestion reports state 'completed'
  console.log(ingestion.ingestionId, ingestion.state)
}

The example shows the flow; live server validation inside run is authoritative for exact parameters.

Video input, which is a URL the provider must reach

generateVideo animates a source image given as an HTTPS URL, with an optional endImageUrl for the final frame. The provider fetches that URL itself, so it has to be reachable from Higgsfield and not merely from your runtime. Local paths, data URIs, and plain HTTP are all rejected by the parameter schema before the call goes anywhere.

When the source image already lives in Files, files.getReadLink mints a signed HTTPS URL that satisfies this. It expires in roughly fifteen minutes, so mint it immediately before submitting rather than early in a long plan, and treat an expired link as a re-mint rather than a retry of the generation.

Cancelling, and the errors worth recognizing

cancelRequest is receipted like a generation and works only while the request is still queued. A success is an acknowledgement that the cancellation was requested, nothing more; the request is not cancelled until getRequestStatus reports canceled. A refusal at HTTP 400 means processing already started, and that is final: there is no later window in which the same cancel would succeed, so poll for the real terminal state instead of retrying.

const { replayed, cancellationRequested } = await higgsfield.cancelRequest({
  sourceId,
  operationId: '019f2c8c-4e77-7b19-9a08-2c7d5f31be64',
  requestId,
})

// acknowledgement only; confirm the terminal state on a later poll
const after = await higgsfield.getRequestStatus({ sourceId, requestId })
console.log(cancellationRequested, after.status)

The example shows the flow; live server validation inside run is authoritative for exact parameters.

Provider errors arrive as short classified text with the provider's own body stripped out, so read the classification rather than hunting for detail that is not there. insufficient_credits means the account cannot pay for this request and no retry helps. not_found on a status read means the requestId or the connected account is wrong. validation_error means the input shape was refused. model_unavailable is the one genuinely transient class, worth a backed-off retry on reads. A 400 on a generate is ambiguous by nature, either bad input or active work already in flight, and the connector cannot distinguish them for you. A 401 is treated as a rejected credential for that call rather than a retryable blip.

For discovery, ask guide a direct question such as How do I generate an image with Higgsfield?. For exact parameters, live server validation inside run is authoritative.

Oddlynew PublicSign in

Referenced by