abler.io

Abler (abler.io)

Kids' sports platform used by Icelandic clubs (ÍR, Valur, Þróttur, Ármann…): profile and children, managed age groups, event details, and per-player attendance and payment status. The app has no public API — ops run inside an agent-browser session against its GraphQL endpoint.

v0.1.0 4/4 verified sportskidsattendancepaymentssession
jokull <https://github.com/jokull> · https://www.abler.io
ab-plus add abler.io && ab-plus login abler.io && ab-plus run abler.io/<op>

Auth rail

Phone code (phone-code) Phone number + SMS code — the runner drives the headed window (fills phone, submits), the human reads the code from their phone, the runner types it in. reCAPTCHA/eID gates run in the real browser.

Auth paths

session ●
Phone number + SMS code sign-on (reCAPTCHA-gated, so it runs in a real browser): the runner fills the phone field and submits, the human reads the SMS code, the runner types it into the OTP boxes. Session persists via --restore; ops run in-session via eval against /graphql.
ttl: session

Auth paths

session ●
Phone number + SMS code sign-on (reCAPTCHA-gated, so it runs in a real browser): the runner fills the phone field and submits, the human reads the SMS code, the runner types it into the OTP boxes. Session persists via --restore; ops run in-session via eval against /graphql.
ttl: session

Operations

Op Kind Risk Requires Description
abler.io/me graphql read-only The signed-in user: name, ssn, email, family members, children, their age groups (with sport and groups), and age-group roles.
returns idstring displayNamestring firstNamestring lastNamestring emailstring ssnstring childrenarray<object> userAgeGroupsarray<object> ageGroupRolesarray<object>
verified 2026-08-25
raw output schema
{
  "type": "object",
  "properties": {
    "id": {
      "type": "string"
    },
    "displayName": {
      "type": "string"
    },
    "firstName": {
      "type": "string"
    },
    "lastName": {
      "type": "string"
    },
    "email": {
      "type": "string"
    },
    "ssn": {
      "type": "string",
      "description": "Kennitala"
    },
    "children": {
      "type": "array",
      "items": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string"
          },
          "firstName": {
            "type": "string"
          },
          "lastName": {
            "type": "string"
          },
          "displayName": {
            "type": "string"
          }
        }
      }
    },
    "userAgeGroups": {
      "type": "array",
      "items": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string"
          },
          "name": {
            "type": "string"
          },
          "isActive": {
            "type": "boolean"
          },
          "sport": {
            "type": "object",
            "properties": {
              "id": {
                "type": "string"
              },
              "name": {
                "type": "string"
              }
            }
          },
          "groups": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "id": {
                  "type": "string"
                },
                "name": {
                  "type": "string"
                },
                "label": {
                  "type": "string"
                }
              }
            }
          }
        }
      }
    },
    "ageGroupRoles": {
      "type": "array",
      "items": {
        "type": "object",
        "properties": {
          "ageGroupId": {
            "type": "string"
          },
          "role": {
            "type": "string"
          },
          "memberVisibility": {
            "type": "string"
          }
        }
      }
    }
  }
}
abler.io/dashboard graphql read-only The age groups and clubs the user manages (coach/organization view) — id, name, label, sport and club per node.
returns idstring namestring labelstring logostring | null ageGroupobject clubobject
verified 2026-08-25
input
{
  "type": "object",
  "properties": {
    "clubIds": {
      "type": "array",
      "items": {
        "type": "string"
      },
      "description": "Optional club id filter"
    },
    "first": {
      "type": "integer",
      "description": "Page size (default 25)"
    }
  }
}
raw output schema
{
  "type": "object",
  "properties": {
    "id": {
      "type": "string"
    },
    "name": {
      "type": "string"
    },
    "label": {
      "type": "string"
    },
    "logo": {
      "type": [
        "string",
        "null"
      ]
    },
    "ageGroup": {
      "type": "object",
      "properties": {
        "id": {
          "type": "string"
        },
        "name": {
          "type": "string"
        },
        "sport": {
          "type": "object",
          "properties": {
            "id": {
              "type": "string"
            },
            "name": {
              "type": "string"
            }
          }
        }
      }
    },
    "club": {
      "type": "object",
      "properties": {
        "id": {
          "type": "string"
        },
        "name": {
          "type": "string"
        }
      }
    }
  }
}
abler.io/event graphql read-only One event by id: name, type, time window, registration window, location, groups, coaches, stats (present/absent/going counts) and the user's own attendance status.
returns idstring eventIdstring namestring typestring descriptionstring | null fromstring | null tostring | null locationAddressstring | null locationLinkstring | null groupNamestring | null groupLabelstring | null homeTeamstring | null awayTeamstring | null opponentstring | null resultstring | null statusstring | null eventPlayerStatsobject currentPlayerAttendanceobject
verified 2026-08-25
input
{
  "type": "object",
  "properties": {
    "id": {
      "type": "string",
      "description": "Event id, e.g. RXZlbnQ6NDQ0MDUwMw=="
    },
    "ageGroupId": {
      "type": "string",
      "description": "Optional age group id for context"
    }
  }
}
raw output schema
{
  "type": "object",
  "properties": {
    "id": {
      "type": "string"
    },
    "eventId": {
      "type": "string"
    },
    "name": {
      "type": "string"
    },
    "type": {
      "type": "string"
    },
    "description": {
      "type": [
        "string",
        "null"
      ]
    },
    "from": {
      "type": [
        "string",
        "null"
      ],
      "description": "ISO datetime"
    },
    "to": {
      "type": [
        "string",
        "null"
      ],
      "description": "ISO datetime"
    },
    "locationAddress": {
      "type": [
        "string",
        "null"
      ]
    },
    "locationLink": {
      "type": [
        "string",
        "null"
      ]
    },
    "groupName": {
      "type": [
        "string",
        "null"
      ]
    },
    "groupLabel": {
      "type": [
        "string",
        "null"
      ]
    },
    "homeTeam": {
      "type": [
        "string",
        "null"
      ]
    },
    "awayTeam": {
      "type": [
        "string",
        "null"
      ]
    },
    "opponent": {
      "type": [
        "string",
        "null"
      ]
    },
    "result": {
      "type": [
        "string",
        "null"
      ]
    },
    "status": {
      "type": [
        "string",
        "null"
      ]
    },
    "eventPlayerStats": {
      "type": "object",
      "properties": {
        "totalCount": {
          "type": "integer"
        },
        "presentCount": {
          "type": "integer"
        },
        "absentCount": {
          "type": "integer"
        },
        "goingCount": {
          "type": "integer"
        },
        "notGoingCount": {
          "type": "integer"
        },
        "maybeCount": {
          "type": "integer"
        },
        "notRespondedCount": {
          "type": "integer"
        }
      }
    },
    "currentPlayerAttendance": {
      "type": "object",
      "properties": {
        "id": {
          "type": "string"
        },
        "status": {
          "type": [
            "string",
            "null"
          ]
        },
        "comment": {
          "type": [
            "string",
            "null"
          ]
        },
        "coachStatus": {
          "type": [
            "string",
            "null"
          ]
        },
        "paymentStatus": {
          "type": [
            "string",
            "null"
          ]
        }
      }
    }
  }
}
abler.io/event-players graphql read-only Per-player rows for one event: attendance status (going / not going / no response), coach status, payment status, waiting list, plus player profile (birth day, jersey number, position, groups, attendance history). Filterable by attendance or payment status.
returns idstring statusstring | null statusExtstring | null commentstring | null coachStatusstring | null coachCommentstring | null paymentStatusstring | null orderIdstring | null waitingListNrinteger | null playerobject
verified 2026-08-25
input
{
  "type": "object",
  "properties": {
    "eventId": {
      "type": "string"
    },
    "ageGroupId": {
      "type": "string"
    },
    "attendanceStatus": {
      "type": "string",
      "description": "Filter, e.g. Going / NotGoing / NotResponded"
    },
    "paymentStatus": {
      "type": "string",
      "description": "Filter, e.g. Paid / Unpaid"
    },
    "first": {
      "type": "integer",
      "description": "Page size (default 15)"
    }
  }
}
raw output schema
{
  "type": "object",
  "properties": {
    "id": {
      "type": "string"
    },
    "status": {
      "type": [
        "string",
        "null"
      ],
      "description": "Attendance: Going / NotGoing / NotResponded / Empty"
    },
    "statusExt": {
      "type": [
        "string",
        "null"
      ]
    },
    "comment": {
      "type": [
        "string",
        "null"
      ]
    },
    "coachStatus": {
      "type": [
        "string",
        "null"
      ]
    },
    "coachComment": {
      "type": [
        "string",
        "null"
      ]
    },
    "paymentStatus": {
      "type": [
        "string",
        "null"
      ]
    },
    "orderId": {
      "type": [
        "string",
        "null"
      ]
    },
    "waitingListNr": {
      "type": [
        "integer",
        "null"
      ]
    },
    "player": {
      "type": "object",
      "properties": {
        "id": {
          "type": "string"
        },
        "firstName": {
          "type": "string"
        },
        "displayName": {
          "type": "string"
        },
        "birthDay": {
          "type": [
            "string",
            "null"
          ]
        },
        "email": {
          "type": [
            "string",
            "null"
          ]
        },
        "phoneNumber": {
          "type": [
            "string",
            "null"
          ]
        },
        "jerseyNumber": {
          "type": [
            "string",
            "null"
          ]
        },
        "position": {
          "type": [
            "string",
            "null"
          ]
        },
        "attendanceHistoryPercentage": {
          "type": [
            "number",
            "null"
          ]
        },
        "groups": {
          "type": "array",
          "items": {
            "type": "object",
            "properties": {
              "id": {
                "type": "string"
              },
              "name": {
                "type": "string"
              },
              "label": {
                "type": "string"
              }
            }
          }
        }
      }
    }
  }
}

Raw artifacts

The manifest is the discovery record — the schema, the docs, and the search index in one file. manifest.json · recipe.ts · README.md