Skip to content

Connect a marketplace or replace its API key

PUT
/marketplaces/{marketplace}
curl --request PUT \
--url https://api.flotera.com/api/v1/marketplaces/vast \
--header 'Content-Type: application/json' \
--cookie __Host-erm_session=<__Host-erm_session> \
--data '{ "api_key": "example" }'

The key is verified against the marketplace before it is stored: a key that the marketplace rejects is never written, so a connected account always means a key that worked at least once.

Re-sending this for an already connected marketplace replaces the key and clears any previous failure — reissuing a revoked key is ordinary, and it must not require disconnecting first, which would drop the server links by cascade.

marketplace
required

Supported marketplace. The database constrains the same two values, so a third one is a migration rather than a new string.

string
Allowed values: vast clore

Marketplace identifier. Closed set: adding one is a migration, not a new string, because the database constrains the same two values.

Idempotency-Key
string
>= 1 characters <= 128 characters /^[\x21-\x7E]{1,128}$/

Idempotency key, 1–128 ASCII, unique per (tenant_id, operation, key) for at least 24 hours. Retrying with the same body replays the stored response; a different body returns 409 idempotency_conflict.

Media typeapplication/json
object
api_key
required

Marketplace API key. Verified against the marketplace before it is stored, and stored only encrypted. Never returned by any endpoint.

string
>= 8 characters <= 512 characters
Examplegenerated
{
"api_key": "example"
}

Marketplace connected.

Media typeapplication/json
object
marketplace
required

Supported marketplace. The database constrains the same two values, so a third one is a migration rather than a new string.

string
Allowed values: vast clore
status
required

invalid_key is set only when the marketplace rejected the key. A network failure, a 5xx or a missing permission group leave the status alone — otherwise the customer would be told to reconnect a marketplace that is working.

string
Allowed values: connected invalid_key disconnected
external_account_id

How the marketplace identifies the account owner.

string | null
<= 128 characters
external_username
string | null
<= 256 characters
credential_digest

Hash of the stored key. Lets the panel tell “the same key” from “a new key” without ever holding the value. The key itself is never returned by any endpoint, in any form.

string | null
<= 64 characters
validated_at

RFC 3339 UTC with microsecond precision, or null.

string | null format: date-time
last_error

Why the last sync failed. Survives until the next success, because it is the only explanation the customer gets for a stalled sync.

string | null
<= 512 characters
last_error_at

RFC 3339 UTC with microsecond precision, or null.

string | null format: date-time
clore_poh_balance

CLORE held in Proof of Holding by this account. The holding cuts the marketplace’s base share in steps, so what a MACHINE is charged depends on this fact about the ACCOUNT. Null means UNREAD, not zero. Zero is a measured “nothing held”, and the full share follows from it; null leaves open that the share is half of what is shown. A reader that treats them alike quotes the owner someone else’s price for their own machine. Only one number leaves the account snapshot, never the snapshot itself — the owner’s wallets live there too. Always null on Vast, which has no such mechanism.

string | null
<= 40 characters /^[0-9]+(\.[0-9]+)?$/
Example
{
"marketplace": "vast",
"status": "connected"
}

Missing/invalid credentials (code=unauthorized).

Media typeapplication/problem+json

RFC 9457 problem document with a stable machine code.

object
type
required
string format: uri
title
required
string
<= 256 characters
status
required
integer
>= 100 <= 599
code
required

Stable machine-readable error code (03 §2.4).

string
Allowed values: unauthorized forbidden csrf_rejected not_found conflict idempotency_conflict validation_failed rate_limited payload_too_large unsupported_agent_version temporarily_unavailable offline_queue_full online_queue_full plan_required server_limit_reached feature_not_entitled account_in_grace account_frozen payment_pending payment_expired payment_amount_mismatch change_already_pending change_already_applied change_effective reserve_not_covered direction_changed
detail
string
<= 2048 characters
instance
string
<= 512 characters
request_id

UUID (v7 for new entities; v4 accepted during migration).

string format: uuid
errors
Array<object>
<= 100 items
object
path
required

JSON Pointer to the offending field.

string
<= 512 characters
code
required
string
<= 64 characters
Example
{
"type": "https://ermeon.com/problems/validation",
"code": "unauthorized"
}

Authenticated but not permitted. code=forbidden — role/scope mismatch; code=feature_not_entitled — the plan does not include the capability; code=account_frozen — the account is frozen and this operation is declared x-ermeon-frozen: deny. The three are deliberately distinct: only the last one is fixed by a top-up (13 §5.6).

Media typeapplication/problem+json

RFC 9457 problem document with a stable machine code.

object
type
required
string format: uri
title
required
string
<= 256 characters
status
required
integer
>= 100 <= 599
code
required

Stable machine-readable error code (03 §2.4).

string
Allowed values: unauthorized forbidden csrf_rejected not_found conflict idempotency_conflict validation_failed rate_limited payload_too_large unsupported_agent_version temporarily_unavailable offline_queue_full online_queue_full plan_required server_limit_reached feature_not_entitled account_in_grace account_frozen payment_pending payment_expired payment_amount_mismatch change_already_pending change_already_applied change_effective reserve_not_covered direction_changed
detail
string
<= 2048 characters
instance
string
<= 512 characters
request_id

UUID (v7 for new entities; v4 accepted during migration).

string format: uuid
errors
Array<object>
<= 100 items
object
path
required

JSON Pointer to the offending field.

string
<= 512 characters
code
required
string
<= 64 characters
Example
{
"type": "https://ermeon.com/problems/validation",
"code": "unauthorized"
}

The marketplace rejected this key. The key is not stored — a connected account always means a key that worked at least once.

Media typeapplication/problem+json

RFC 9457 problem document with a stable machine code.

object
type
required
string format: uri
title
required
string
<= 256 characters
status
required
integer
>= 100 <= 599
code
required

Stable machine-readable error code (03 §2.4).

string
Allowed values: unauthorized forbidden csrf_rejected not_found conflict idempotency_conflict validation_failed rate_limited payload_too_large unsupported_agent_version temporarily_unavailable offline_queue_full online_queue_full plan_required server_limit_reached feature_not_entitled account_in_grace account_frozen payment_pending payment_expired payment_amount_mismatch change_already_pending change_already_applied change_effective reserve_not_covered direction_changed
detail
string
<= 2048 characters
instance
string
<= 512 characters
request_id

UUID (v7 for new entities; v4 accepted during migration).

string format: uuid
errors
Array<object>
<= 100 items
object
path
required

JSON Pointer to the offending field.

string
<= 512 characters
code
required
string
<= 64 characters
Example
{
"type": "https://ermeon.com/problems/validation",
"code": "unauthorized"
}

The marketplace could not be reached to verify the key, or the integration is not configured. Retriable; the key is not stored. Deliberately not reported as a rejected key: the key may be perfectly good.

Media typeapplication/problem+json

RFC 9457 problem document with a stable machine code.

object
type
required
string format: uri
title
required
string
<= 256 characters
status
required
integer
>= 100 <= 599
code
required

Stable machine-readable error code (03 §2.4).

string
Allowed values: unauthorized forbidden csrf_rejected not_found conflict idempotency_conflict validation_failed rate_limited payload_too_large unsupported_agent_version temporarily_unavailable offline_queue_full online_queue_full plan_required server_limit_reached feature_not_entitled account_in_grace account_frozen payment_pending payment_expired payment_amount_mismatch change_already_pending change_already_applied change_effective reserve_not_covered direction_changed
detail
string
<= 2048 characters
instance
string
<= 512 characters
request_id

UUID (v7 for new entities; v4 accepted during migration).

string format: uuid
errors
Array<object>
<= 100 items
object
path
required

JSON Pointer to the offending field.

string
<= 512 characters
code
required
string
<= 64 characters
Example
{
"type": "https://ermeon.com/problems/validation",
"code": "unauthorized"
}