> ## Documentation Index
> Fetch the complete documentation index at: https://hs-df36fa00.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Submit an Agent for Review — POST /v1/agent-submissions

> Submit an A2A-compatible agent to the registry. Valid submissions are auto-approved by default. Returns the AgentSubmissionRecord with status.

Submits a new agent to the ServiceNet registry. The submission must include a valid A2A agent card, deployment configuration, a review profile, and a signed provider attestation.

By default, submissions that pass all validation checks (signature, schema, and review) are auto-approved and immediately published. Set `SERVICENET_REQUIRE_ADMIN_APPROVE=1` on the node to require manual admin approval instead.

***

## Submit an agent

### `POST /v1/agent-submissions`

```bash theme={null}
curl -X POST http://your-node:8042/v1/agent-submissions \
  -H 'content-type: application/json' \
  -d '{
    "provider_id": "acme-labs",
    "agent_id": "stripe-agent",
    "version": "0.1.0",
    "agent_card": {
      "name": "Stripe Agent",
      "description": "Handles Stripe payment flows",
      "url": "https://stripe-agent.example.com",
      "preferredTransport": "JSONRPC",
      "protocolVersion": "1.0",
      "supportsTask": false,
      "skills": [
        {
          "id": "payments.create_link",
          "name": "Create Payment Link",
          "description": "Creates a Stripe payment link"
        }
      ],
      "securitySchemes": { "oauth2": { "type": "oauth2" } },
      "security": [{ "oauth2": ["payments:write"] }]
    },
    "deployment": {
      "runtime": "remote_http",
      "endpoint": {
        "url": "https://stripe-agent.example.com/a2a",
        "protocol_binding": "JSONRPC",
        "protocol_version": "1.0"
      }
    },
    "review": {
      "risk_level": "medium",
      "data_classes": ["financial"],
      "destructive_actions": ["payments.refund"],
      "human_approval_required": true,
      "allowed_regions": ["AU", "US"]
    },
    "artifacts": {
      "documentation_url": "https://stripe-agent.example.com/docs",
      "security_url": "https://stripe-agent.example.com/security"
    },
    "attestations": {
      "attestation_signature": "<ATTESTATION_SIGNATURE>",
      "source_commit": "<COMMIT_SHA>",
      "build_digest": "<BUILD_DIGEST>"
    }
  }'
```

### Body parameters

<ParamField body="provider_id" type="string" required>
  The `provider_id` of the registered, active provider submitting this agent.
</ParamField>

<ParamField body="agent_id" type="string" required>
  Unique identifier for this agent (e.g. `"stripe-agent"`). Must be unique within the provider's submissions.
</ParamField>

<ParamField body="version" type="string" required>
  Semantic version for this release (e.g. `"0.1.0"`).
</ParamField>

<ParamField body="agent_card" type="object" required>
  A2A-compatible agent card object. Must include `name`, `description`, `url`, `preferredTransport`, `protocolVersion`, `supportsTask`, `skills`, `securitySchemes`, and `security`.
</ParamField>

<ParamField body="deployment" type="object" required>
  Deployment configuration.

  <Expandable title="deployment fields">
    <ParamField body="runtime" type="string" required>
      Execution runtime identifier (e.g. `"remote_http"`).
    </ParamField>

    <ParamField body="endpoint" type="object" required>
      <Expandable title="endpoint fields">
        <ParamField body="url" type="string" required>
          The publicly reachable A2A endpoint URL.
        </ParamField>

        <ParamField body="protocol_binding" type="string" required>
          Protocol binding (e.g. `"JSONRPC"`).
        </ParamField>

        <ParamField body="protocol_version" type="string" required>
          Protocol version (e.g. `"1.0"`).
        </ParamField>

        <ParamField body="interaction_protocol" type="string">
          Interaction protocol. Defaults to `"google_a2a"`.
        </ParamField>
      </Expandable>
    </ParamField>
  </Expandable>
</ParamField>

<ParamField body="review" type="object" required>
  Review profile for this agent.

  <Expandable title="review fields">
    <ParamField body="risk_level" type="string" required>
      One of `"low"`, `"medium"`, or `"high"`.
    </ParamField>

    <ParamField body="data_classes" type="string[]">
      Categories of data handled (e.g. `["financial"]`).
    </ParamField>

    <ParamField body="destructive_actions" type="string[]">
      List of destructive action identifiers.
    </ParamField>

    <ParamField body="human_approval_required" type="boolean">
      Whether invocations require human confirmation.
    </ParamField>

    <ParamField body="allowed_regions" type="string[]">
      ISO country codes where the agent may operate.
    </ParamField>

    <ParamField body="cost_per_call_units" type="integer">
      Cost in abstract units per invocation.
    </ParamField>
  </Expandable>
</ParamField>

<ParamField body="artifacts" type="object">
  Optional supporting artifact URLs.

  <Expandable title="artifacts fields">
    <ParamField body="documentation_url" type="string">
      Link to the agent's public documentation.
    </ParamField>

    <ParamField body="security_url" type="string">
      Link to the agent's security disclosure page.
    </ParamField>

    <ParamField body="smoke_test_report_url" type="string">
      Link to an automated smoke test report for this version.
    </ParamField>
  </Expandable>
</ParamField>

<ParamField body="attestations" type="object" required>
  Provider attestation proving the submission's integrity.

  <Expandable title="attestations fields">
    <ParamField body="attestation_signature" type="string" required>
      Base64-encoded signature over the canonical attestation payload, which covers all submission fields including `provider_id`, `agent_id`, `version`, `agent_card`, `deployment`, `review`, `artifacts`, and all attestation metadata fields.
    </ParamField>

    <ParamField body="provider_attester_did" type="string">
      DID of the attesting party, if different from the provider DID.
    </ParamField>

    <ParamField body="delegation_token" type="string">
      Optional delegation token proving the attesting DID is authorised to sign on behalf of the provider.
    </ParamField>

    <ParamField body="source_commit" type="string">
      Git commit SHA of the source used for this build.
    </ParamField>

    <ParamField body="build_digest" type="string">
      Content digest of the build artifact (e.g. OCI image digest).
    </ParamField>

    <ParamField body="nonce" type="string">
      Unique nonce for this submission. Nodes may reject duplicate nonces from the same provider.
    </ParamField>

    <ParamField body="issued_at_ms" type="integer">
      Unix timestamp in milliseconds when the attestation was signed. Nodes may reject stale timestamps.
    </ParamField>

    <ParamField body="expires_at_ms" type="integer">
      Unix timestamp in milliseconds after which this submission must be rejected.
    </ParamField>
  </Expandable>
</ParamField>

### Response

Returns the created `AgentSubmissionRecord` with status `201 Created`.

<ResponseField name="submission_id" type="string (UUID)">
  Unique identifier for this submission. Use it to query status or approve/reject via the admin API.
</ResponseField>

<ResponseField name="provider_id" type="string">
  The submitting provider's identifier.
</ResponseField>

<ResponseField name="agent_id" type="string">
  The agent identifier.
</ResponseField>

<ResponseField name="version" type="string">
  The submitted version.
</ResponseField>

<ResponseField name="status" type="string">
  Submission lifecycle status. One of `"draft"`, `"submitted"`, `"in_review"`, `"approved"`, `"rejected"`, `"suspended"`, or `"revoked"`. Auto-approved submissions will be `"approved"`.
</ResponseField>

<ResponseField name="agent_card" type="object">
  The submitted A2A agent card.
</ResponseField>

<ResponseField name="deployment" type="object">
  The submitted deployment configuration.
</ResponseField>

<ResponseField name="review" type="AgentReviewProfile">
  The submitted review profile.
</ResponseField>

<ResponseField name="artifacts" type="AgentArtifacts">
  The submitted artifact URLs.
</ResponseField>

<ResponseField name="attestations" type="AgentAttestations">
  The submitted attestation data.
</ResponseField>

<ResponseField name="submitted_at" type="string">
  ISO 8601 timestamp of submission.
</ResponseField>

<ResponseField name="updated_at" type="string">
  ISO 8601 timestamp of the most recent status change.
</ResponseField>

<ResponseField name="reviewed_by" type="string">
  Reviewer identity. Set to `"auto-approve"` for automatically approved submissions.
</ResponseField>

<ResponseField name="review_notes" type="string">
  Optional reviewer notes.
</ResponseField>

<ResponseField name="rejection_reason" type="string">
  Reason for rejection. Present only when `status` is `"rejected"`.
</ResponseField>

### Status codes

| Code              | Meaning                                                                               |
| ----------------- | ------------------------------------------------------------------------------------- |
| `201 Created`     | Submission accepted. Returns the `AgentSubmissionRecord`.                             |
| `400 Bad Request` | Missing required fields, invalid attestation signature, or schema validation failure. |
| `403 Forbidden`   | The provider is revoked or blocked.                                                   |

### Example response

```json theme={null}
{
  "submission_id": "a1b2c3d4-0000-0000-0000-000000000001",
  "provider_id": "acme-labs",
  "agent_id": "stripe-agent",
  "version": "0.1.0",
  "status": "approved",
  "agent_card": { "name": "Stripe Agent", "..." : "..." },
  "deployment": {
    "runtime": "remote_http",
    "endpoint": {
      "url": "https://stripe-agent.example.com/a2a",
      "protocol_binding": "JSONRPC",
      "protocol_version": "1.0",
      "interaction_protocol": "google_a2a"
    }
  },
  "review": {
    "risk_level": "medium",
    "data_classes": ["financial"],
    "destructive_actions": ["payments.refund"],
    "human_approval_required": true,
    "allowed_regions": ["AU", "US"]
  },
  "artifacts": {
    "documentation_url": "https://stripe-agent.example.com/docs"
  },
  "attestations": {
    "attestation_signature": "<ATTESTATION_SIGNATURE>",
    "source_commit": "abc123"
  },
  "submitted_at": "2025-01-16T07:55:00Z",
  "updated_at": "2025-01-16T07:55:01Z",
  "reviewed_by": "auto-approve"
}
```

***

## List submissions

### `GET /v1/agent-submissions`

Retrieve submissions filtered by provider, agent, or status.

```bash theme={null}
curl 'http://your-node:8042/v1/agent-submissions?provider_id=acme-labs&status=approved'
```

### Query parameters

<ParamField query="provider_id" type="string">
  Filter by provider identifier.
</ParamField>

<ParamField query="agent_id" type="string">
  Filter by agent identifier.
</ParamField>

<ParamField query="status" type="string">
  Filter by submission status. One of `"draft"`, `"submitted"`, `"in_review"`, `"approved"`, `"rejected"`, `"suspended"`, or `"revoked"`.
</ParamField>

Returns `{ "items": AgentSubmissionRecord[] }`.

***

## Get a single submission

### `GET /v1/agent-submissions/:submission_id`

```bash theme={null}
curl http://your-node:8042/v1/agent-submissions/a1b2c3d4-0000-0000-0000-000000000001
```

<ParamField path="submission_id" type="string (UUID)" required>
  The `submission_id` returned when the submission was created.
</ParamField>

Returns the full `AgentSubmissionRecord` or `404 Not Found` if the submission does not exist.
