Skip to main content
Groups exist so you can follow good traders without watching the charts. Turn on auto-buy for a group and every new call its leaders post gets mirrored into your wallet at a fixed size you choose. Set it once, and the group trades for you. Everything else on this page — joining, leaving, and the admin flows for running your own group — is in service of that goal.
Every monetary value on the wire is a full-precision decimal string in USD. Group fees (joiningFee, subscriptionFee) are whole-dollar amounts sent as strings ("0", "10"); the auto-buy amountUsd is a decimal string ("25.00"). Never send a number or raw base units. See Money & precision.
Set up your environment before starting:
export MURMO_API_KEY="murmo_your_key_here"
export MURMO_BASE="https://api.alpha-labs.trade"

Auto-buy: follow a group automatically

POST /api/v1/groups/{id}/auto-buy sets your copy-trade follow for one group. With { "enabled": true, "amountUsd": "25.00" }, every new call from that group is mirrored into your wallet at a fixed $25 size. Send { "enabled": false } to turn it off.
curl -X POST "$MURMO_BASE/api/v1/groups/GROUP_ID/auto-buy" \
  -H "Authorization: Bearer $MURMO_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "enabled": true, "amountUsd": "25.00" }'
Response
{
  "data": {
    "userDynamicId": "usr_abc123",
    "groupId": "GROUP_ID",
    "memberType": "MEMBER",
    "username": "satoshi",
    "avatar": null,
    "subscriptionStatus": null,
    "nextChargeAt": null,
    "autoBuyEnabled": true,
    "autoBuyAmountUsd": "25",
    "createdAt": "2026-06-01T12:00:00.000Z",
    "updatedAt": "2026-06-03T09:30:00.000Z"
  }
}
To stop following, disable without an amount:
curl -X POST "$MURMO_BASE/api/v1/groups/GROUP_ID/auto-buy" \
  -H "Authorization: Bearer $MURMO_API_KEY" -H "Content-Type: application/json" \
  -d '{ "enabled": false }'
enabled (a boolean) is required. Omit it, or send anything other than true/false, and you get a 400. amountUsd is the fixed follow size and is only meaningful when enabled is true.
Auto-buy only sizes the entry. You manage your own positions afterward — sell or close them through the Spot trading, Prediction markets, and Perpetuals guides.

Follow a group in 3 steps

1

Find a group you're in

GET /api/v1/groups returns the groups you belong to. Grab a uniqueId to follow. There is no endpoint to discover other people’s groups — join via an invite or a public group ID first (see Membership below).
curl "$MURMO_BASE/api/v1/groups" -H "Authorization: Bearer $MURMO_API_KEY"
2

Turn on auto-buy

Call POST /api/v1/groups/{id}/auto-buy with { "enabled": true, "amountUsd": "25.00" }. The response echoes your membership record with autoBuyEnabled: true.
3

The group trades for you

From now on, every new call the group’s leaders post is mirrored into your wallet at $25. To see what’s being called, read the group’s proposals (GET /api/v1/groups/{id}/proposals) or your aggregated positions. Change the size by calling auto-buy again with a new amountUsd; stop with { "enabled": false }.

Membership

List your groups

GET /api/v1/groups returns only your groups — the ones you’re a member of. There is deliberately no endpoint to discover other people’s groups; private group internals stay private.
curl "$MURMO_BASE/api/v1/groups" -H "Authorization: Bearer $MURMO_API_KEY"
data is an array of Group objects enriched with per-user data (your performanceRank, unread counts, etc.). Key fields:
FieldTypeNotes
uniqueIdstringThe group ID you pass as {id} everywhere.
name, description, image, headerstring / nullDisplay fields.
joiningFee, subscriptionFeedecimal stringWhole-dollar fees, e.g. "0", "10".
groupAccessTypeenumPUBLIC or PRIVATE.
defaultMemberTypeenumLEADER or MEMBER — the role new joiners get.
isActivebooleanWhether the group is active.
performancePnlobject / null{ allTimePnl, pnl7Days, pnl30Days }, each a decimal string.
winRate, avgReturn, volatilitydecimal string / nullPercentages as decimal strings (e.g. "42.7" = 42.7%).
tradeCount, memberCount, performanceRankinteger / nullStructural counts.

Join a group

POST /api/v1/groups/{id}/join — how it resolves depends on the group type and the body:
  • PUBLIC group → you join immediately. Response status is JOINED, with your full membership.
  • PRIVATE group → a join request is created for leaders to approve. Response status is REQUESTED. Once approved, call join again with { "finalize": true } to finalize (status: JOINED).
  • { "inviteCode": "..." } → routes by the code and ignores the group type: a public invite joins you immediately (JOINED), a private invite creates a request (REQUESTED).
curl -X POST "$MURMO_BASE/api/v1/groups/GROUP_ID/join" \
  -H "Authorization: Bearer $MURMO_API_KEY" -H "Content-Type: application/json" \
  -d '{}'
Joined response
{
  "data": {
    "status": "JOINED",
    "membership": {
      "userDynamicId": "usr_abc123",
      "groupId": "GROUP_ID",
      "memberType": "MEMBER",
      "autoBuyEnabled": false,
      "autoBuyAmountUsd": null,
      "createdAt": "2026-06-03T09:30:00.000Z"
    }
  }
}
Requested response (private group)
{
  "data": {
    "status": "REQUESTED",
    "groupId": "GROUP_ID",
    "userDynamicId": "usr_abc123",
    "memberType": "MEMBER"
  }
}
Branch on the status field — JOINED vs REQUESTED. Don’t assume a join succeeded just because you got a 200: a REQUESTED response means you’re still waiting on a leader’s approval. A non-existent group ID (without an invite code) returns 404.
If the group charges a joiningFee or subscriptionFee, joining settles that fee against your cash balance. Check them on the Group object before you join.

Leave a group

POST /api/v1/groups/{id}/leave queues a background job that sells your positions in the group and then removes your membership. It returns immediately with status: "EXITING" — the exit is not instantaneous.
curl -X POST "$MURMO_BASE/api/v1/groups/GROUP_ID/leave" \
  -H "Authorization: Bearer $MURMO_API_KEY"
Response
{ "data": { "groupId": "GROUP_ID", "status": "EXITING" } }

Pay your subscription

If your membership is past due, POST /api/v1/groups/{id}/subscription charges the subscription fee against your cash balance and returns your refreshed member record (with subscriptionStatus and nextChargeAt).
curl -X POST "$MURMO_BASE/api/v1/groups/GROUP_ID/subscription" \
  -H "Authorization: Bearer $MURMO_API_KEY"
The response data is a GroupMember object.

The group’s proposals

GET /api/v1/groups/{id}/proposals returns every open call in the group — spot/perp and prediction — as one combined object. Use it to see what auto-buy is mirroring or to act on a call yourself.
curl "$MURMO_BASE/api/v1/groups/GROUP_ID/proposals" \
  -H "Authorization: Bearer $MURMO_API_KEY"
Response (shape)
{
  "data": {
    "tradingProposals": [ { "...": "spot/perp proposal + your position" } ],
    "predictionProposals": [ { "...": "prediction proposal + your position" } ]
  }
}
data is an object keyed by vertical, not an array. Each entry carries the proposal plus your own position in it. To open or manage positions, see the per-vertical guides: Spot trading, Prediction markets, and Perpetuals.
Every per-group read (proposals, agents, join-requests) is gated to members. If you’re not in the group you get 403 with code: NOT_GROUP_MEMBER. See Errors.

Run your own group

Create a group

POST /api/v1/groups — the caller becomes the group ADMIN. name, joiningFee, and groupAccessType are required; fees are whole-dollar strings.
curl -X POST "$MURMO_BASE/api/v1/groups" \
  -H "Authorization: Bearer $MURMO_API_KEY" -H "Content-Type: application/json" \
  -d '{
    "name": "Alpha Callers",
    "description": "High-conviction spot calls.",
    "joiningFee": "0",
    "subscriptionFee": "10",
    "groupAccessType": "PRIVATE",
    "defaultMemberType": "MEMBER"
  }'
Response
{
  "data": {
    "groupId": "GROUP_ID",
    "membership": {
      "userDynamicId": "usr_abc123",
      "groupId": "GROUP_ID",
      "memberType": "ADMIN",
      "autoBuyEnabled": false,
      "autoBuyAmountUsd": null,
      "createdAt": "2026-06-03T09:30:00.000Z"
    }
  }
}
Body fieldRequiredTypeNotes
nameyesstringGroup display name.
joiningFeeyesdecimal stringWhole-dollar one-time join fee, e.g. "0".
groupAccessTypeyesenumPUBLIC or PRIVATE.
subscriptionFeenodecimal stringWhole-dollar recurring fee.
defaultMemberTypenoenumLEADER or MEMBER for new joiners (default MEMBER).
description, header, imagenostringDisplay fields.
joiningFee is required and must be a whole-dollar string — use "0" for a free group. A missing or malformed joiningFee, name, or groupAccessType returns 400.

Update group settings

PATCH /api/v1/groups/{id}leaders and admins only. Send only the fields you want to change.
curl -X PATCH "$MURMO_BASE/api/v1/groups/GROUP_ID" \
  -H "Authorization: Bearer $MURMO_API_KEY" -H "Content-Type: application/json" \
  -d '{ "subscriptionFee": "15", "isActive": true }'
Accepts the same fields as create, plus isActive (boolean). Returns the updated Group.

Approve or reject join requests

GET /api/v1/groups/{id}/join-requests lists pending REQUESTED members (leaders and admins only).
curl "$MURMO_BASE/api/v1/groups/GROUP_ID/join-requests" \
  -H "Authorization: Bearer $MURMO_API_KEY"
Response
{
  "data": [
    {
      "userDynamicId": "usr_pending1",
      "username": "newtrader",
      "groupId": "GROUP_ID",
      "requestedAt": "2026-06-02T18:00:00.000Z"
    }
  ]
}
Resolve one with POST /api/v1/groups/{id}/join-requests/{userId}/approve. The default action approves; send { "action": "reject" } to reject.
curl -X POST "$MURMO_BASE/api/v1/groups/GROUP_ID/join-requests/usr_pending1/approve" \
  -H "Authorization: Bearer $MURMO_API_KEY" -H "Content-Type: application/json" \
  -d '{}'
Approved response
{
  "data": {
    "status": "APPROVED",
    "groupId": "GROUP_ID",
    "userDynamicId": "usr_pending1",
    "memberType": "MEMBER",
    "autoJoined": false
  }
}
After approval, the requester finalizes their own membership — either it auto-joins (autoJoined: true) or they call join with { "finalize": true }.

Kick and promote members

Both are admin-only and take the target member’s ID in the path.
# Kick a member
curl -X POST "$MURMO_BASE/api/v1/groups/GROUP_ID/members/usr_target/kick" \
  -H "Authorization: Bearer $MURMO_API_KEY"

# Promote MEMBER to LEADER
curl -X POST "$MURMO_BASE/api/v1/groups/GROUP_ID/members/usr_target/promote" \
  -H "Authorization: Bearer $MURMO_API_KEY"
promote returns the updated GroupMember (now with memberType: "LEADER"). kick returns { "data": { "success": true } }.

Group agents

Agents are bots a group admin can switch on inside a group. GET /api/v1/groups/{id}/agents lists the agents configured for the group (members only).
curl "$MURMO_BASE/api/v1/groups/GROUP_ID/agents" \
  -H "Authorization: Bearer $MURMO_API_KEY"
Response (shape)
{
  "data": [
    {
      "id": "ga_1",
      "groupId": "GROUP_ID",
      "agentKey": "alpha-scout",
      "status": "ACTIVE",
      "activatedBy": "usr_abc123",
      "activatedAt": "2026-06-01T12:00:00.000Z",
      "Agent": { "key": "alpha-scout", "displayName": "Alpha Scout" }
    }
  ]
}
Enable or disable one with POST /api/v1/groups/{id}/agents (admin only). agentKey is required; action defaults to enable.
curl -X POST "$MURMO_BASE/api/v1/groups/GROUP_ID/agents" \
  -H "Authorization: Bearer $MURMO_API_KEY" -H "Content-Type: application/json" \
  -d '{ "agentKey": "alpha-scout", "action": "enable" }'
Enable response
{
  "data": {
    "groupAgent": { "id": "ga_1", "groupId": "GROUP_ID", "agentKey": "alpha-scout", "status": "ACTIVE" },
    "paymentRequired": true,
    "pointsTransaction": { "...": "..." }
  }
}
Enabling an agent for the first time spends activation points from the admin’s balance (paymentRequired: true, with a pointsTransaction). Insufficient points returns 400.
Role gating. PATCH, approve/reject, and join-request reads require a leader or admin; kick, promote, and agent enable/disable require an admin. Calling one without the role returns 403. See Errors.

Field reference

GroupMember (auto-buy, promote, subscription responses)

FieldTypeNotes
userDynamicIdstringThe member’s user ID.
groupIdstringThe group.
memberTypeenumLEADER or MEMBER.
username, avatarstring / nullDisplay fields.
subscriptionStatusstring / nullSubscription state.
nextChargeAtdate-time / nullNext subscription charge.
inviteCodestring / nullThe member’s invite code, if any.
autoBuyEnabledbooleanWhether copy-trade follow is on.
autoBuyAmountUsddecimal string / nullThe fixed follow size in USD.
createdAt, updatedAtdate-timeISO timestamps.

Membership (create / join responses)

Same as GroupMember but without username/avatar, plus mainWalletAddress (string / null) and an optional nested group object. On create, memberType is ADMIN.

Where to next

Groups & proposals

The social model: groups, proposals, positions.

Spot Trading

Open, buy, sell, and close spot calls.

Prediction Markets

Predict YES/NO on real-world events.

Perpetuals

Leverage, brackets, and live PnL.

Errors

Status codes and the codes worth handling.

API Reference

Every Groups endpoint, request, and response.