bluesmarties876/skills

Vollständiger Client für die Motion (usemotion.com) REST-API – alle 27 dokumentierten Endpunkte für Aufgaben, Projekte, wiederkehrende Aufgaben, Kommentare, benutzerdefinierte Felder, Benutzer, Arbeitsbereiche, Status und Zeitpläne, plus eine raw-Ausweichmöglichkeit (mit Cursor-Paginierung) für alles Undokumentierte. Handhabt X-API-Key-Authentifizierung, Cursor-Paginierung, Rate-Limit-Backoff und sichert jedes Löschen hinter einem expliziten Bestätigungs-Flag.

Was ist skills?

Dieses Skill bietet einen vollständigen Kommandozeilen-Client für die Motion REST-API (usemotion.com) und deckt alle 27 dokumentierten Endpunkte ab. Es ermöglicht die Verwaltung von Aufgaben, Projekten, wiederkehrenden Aufgaben, Kommentaren, benutzerdefinierten Feldern, Benutzern, Arbeitsbereichen, Status und Zeitplänen. Das Tool unterstützt die Authentifizierung per X-API-Key, Cursor-basierte Paginierung (mit einer `--all`-Option, die automatisch durch alle Seiten navigiert) und ein intelligentes Rate-Limit-Backoff, das 429-Antworten mit `Retry-After`-Respekt behandelt. Ein besonderes Merkmal ist der „raw“-Ausweichmechanismus, der es ermöglicht, beliebige HTTP-Anfragen an die API zu senden – nützlich für Endpunkte, die noch nicht in den benannten Befehlen abgedeckt sind. Das Skill unterstützt Motion für Entwickler und Teams, die Aufgabenverwaltung und Projektplanung automatisieren möchten. Es ist als Python-Skript (`python3 motion.py`) implementiert und wird über die `MOTION_API_KEY`-Umgebungsvariable authentifiziert. Wichtig: Löschvorgänge erfordern ein explizites `--yes`-Flag, um versehentliche Datenverluste zu vermeiden.

Funktioniert mit~Claude Code~Codex CLI✓Cursor
npx skills add https://github.com/bluesmarties876/skills/tree/HEAD/api/motion-api

Installed? Explore more Produktivität & Zusammenarbeit skills: steipete/gemini, steipete/gh-issues, steipete/skill-creator · View all 6 →

In Ihrer bevorzugten KI fragen

Öffnet einen neuen Chat, in dem dieser Agent-Skill bereits geladen ist.

Dokumentation

Motion API

Vollständiger Client für die Motion (usemotion.com) REST-API – alle 27 dokumentierten Endpunkte für Aufgaben, Projekte, wiederkehrende Aufgaben, Kommentare, benutzerdefinierte Felder, Benutzer, Arbeitsbereiche, Status und Zeitpläne, plus eine raw-Ausweichmöglichkeit für alles, was noch nicht dokumentiert ist.

Wann dieses Skill verwendet werden sollte

Verwenden Sie es immer dann, wenn die Arbeit Motion betrifft: Lesen oder Erstellen von Aufgaben, Auflisten von Projekten, Posten von Kommentaren zu Aufgaben, Verwalten wiederkehrender Aufgaben oder Lesen von Arbeitsbereichs-Status, Benutzern und Zeitplänen.

Anmeldeinformationen

Eine Anmeldeinformation, MOTION_API_KEY. Die Plattform injiziert sie als Umgebungsvariable, wenn ein Skript über RunWithCredentials ausgeführt wird – übergeben Sie niemals einen Schlüssel in der Befehlszeile und geben Sie ihn niemals aus oder echoen Sie ihn.

Holen Sie sich einen Schlüssel in Motion unter Einstellungen → API. Motion zeigt ihn nur einmal an, also kopieren Sie ihn sofort. Wenn Aufrufe 401 zurückgeben, wurde der Schlüssel widerrufen oder neu generiert und muss ersetzt werden.

Hinweis: Bei der Proxy-Modus-Auslieferung von Anmeldeinformationen enthält die Umgebungsvariable einen nicht geheimen Platzhalter und der tatsächliche Wert wird in Anfragen an api.usemotion.com injiziert. Ein neu gespeicherter Schlüssel kann einige Minuten brauchen, um sich zu verbreiten; eine sofortige 401, die später erfolgreich ist, ist Verbreitung, kein ungültiger Schlüssel.

Von der API befolgte Konventionen

Dies sind die Fakten, die den Unterschied zwischen einem funktionierenden und einem nicht funktionierenden Aufruf ausmachen.

SacheWert
Basis-URLhttps://api.usemotion.com
Auth-HeaderX-API-Key: <key>
Health-CheckGET /v1/users/me – gibt den Besitzer des Schlüssels zurück
Pfad-Präfixe/v1/ für alles außer benutzerdefinierten Feldern, die unter /beta/ liegen
Ratenbegrenzungen12 Anfragen/min (einzeln), bis zu 120 (Teams), höher für Enterprise
BeschreibungenGithub Flavored Markdown
PrioritätswerteASAP, HOCH, MITTEL, NIEDRIG (wiederkehrende Aufgaben: nur HOCH/MITTEL)
Frist-TypenHART, WEICH, KEINE (wiederkehrende Aufgaben: nur HART/WEICH)

Paginierung. Listen-Endpunkte akzeptieren einen cursor und geben einen Umschlag zurück:

{ "meta": { "nextCursor": "…", "pageSize": 25 }, "tasks": [ … ] }

Der Umschlagschlüssel ist meta, und das Feld für die nächste Seite ist nextCursor. Übergeben Sie --all bei einem beliebigen Listenbefehl und das Skript folgt dem Cursor für Sie und gibt ein flaches Array zurück.

--all stoppt nach 100 Seiten und schlägt dann fehl, sodass eine außer Kontrolle geratene Abfrage einen Lauf nicht aufhängen kann – grenzen Sie die Abfrage ein, wenn Sie dies sehen. Und wenn eine Seite weder ein JSON-Objekt noch ein Array ist (abgeschnitten oder eine Gateway-Fehlerseite), weigert sich der Durchlauf, anstatt das zurückzugeben, was er hat: Eine unvollständige Liste, die vollständig aussieht, ist schlimmer als ein Fehler.

Zwei Listen-Endpunkte geben ein bloßes Array ohne Paginierung zurück – GET /v1/statuses und GET /beta/workspaces/{id}/custom-fields. Alles andere ist umschlossen.

Fehler. Nicht-2xx-Antworten enthalten {"message", "error", "statusCode"}. Die Skripte geben dies als JSON auf stderr aus und beenden mit einem Fehlercode ungleich Null. 429 wird mit Backoff unter Berücksichtigung von Retry-After wiederholt; 400, 401, 403 und 404 werden sofort gemeldet und niemals wiederholt. Validierungsfehler enthalten ein feldbezogenes errors[]-Array; der Client hängt diese Nachrichten an, damit der eigentliche Grund sichtbar ist.

Ein User-Agent ist obligatorisch. Moutons Edge blockiert die Standard-Signatur Python-urllib/x.y mit einem Cloudflare-403 (browser_signature_banned), bevor die Anfrage die API erreicht. Der Client sendet immer motion-api-skill/1.0; wenn Sie Ihre eigene Anfrage gegen diese API schreiben, setzen Sie explizit einen User-Agent, sonst erhalten Sie einen verwirrenden 403 anstelle einer echten Antwort.

Boolesche Abfrageparameter müssen kleingeschrieben sein. Motion analysiert Abfragezeichenfolgen als Text, daher muss ein boolescher Filter das Literal true sein, nicht Pythons True. Dies falsch zu machen, ist keine stille Nicht-Operation: Die API antwortet mit einem verwirrenden 400, der über den entgegengesetzten Wert spricht (siehe den Abschnitt Live-Unterschiede unten). Der Client sendet immer kleingeschriebene Literale.

Befehlsreferenz

Jeder Befehl gibt JSON auf stdout aus. python3 motion.py <gruppe> --help listet die Flags auf.

Aufgaben

BefehlEndpunkt
tasks listGET /v1/tasks
tasks get <task_id>GET /v1/tasks/{id}
tasks createPOST /v1/tasks
tasks update <task_id>PATCH /v1/tasks/{id}
tasks move <task_id> --workspace-id …PATCH /v1/tasks/{id}/move
tasks delete <task_id> --yesDELETE /v1/tasks/{id}
tasks unassign <task_id> --yesDELETE /v1/tasks/{id}/assignee

tasks list Filter: --assignee-id, --project-id, --workspace-id, --name (groß-/kleinschreibungsunabhängige Teilzeichenfolge), --label (einzeln, ein Label-Name), --status (wiederholbar), --include-all-statuses. --status und --include-all-statuses schließen sich gegenseitig aus – beides zu senden, wird von der API abgelehnt, und die CLI weigert sich frühzeitig mit dieser Nachricht, anstatt eine Anfrage für einen garantierten 400 zu verschwenden.

--include-all-statuses ist die Möglichkeit, eine Aufgabe zu sehen, die über ihren Arbeitsbereichs-Standard hinausgegangen ist (z. B. alles, was in „Backlog" oder „In Review" sitzt); ohne sie gibt GET /v1/tasks nur den Standard-Status zurück und die Liste sieht leer aus. Die Kombination mit --all gibt jede Aufgabe zurück, die jemandem zugewiesen ist, über alle Status hinweg.

tasks create / tasks update akzeptieren die gleichen Felder: --name, --workspace-id, --due-date (ISO 8601; erforderlich für geplante Aufgaben), --duration, --status, --project-id, --description, --priority, --label (wiederholbar), --assignee-id.

--duration akzeptiert eine ganze Anzahl von Minuten oder die Zeichenfolgen KEINE / ERINNERUNG (groß-/kleinschreibungsunabhängig bei der Eingabe, normalisiert zu Großbuchstaben).

Die automatische Planung ist dreiwertig, und der Unterschied ist wichtig:

  • Beide Flags weglassen → das Feld wird aus der Anfrage vollständig weggelassen (unverändert)
  • --auto-scheduled '{"deadlineType":"HART"}' → schaltet sie ein; verschachtelte Felder sind startDate, deadlineType (HART/WEICH/KEINE) und schedule (Standard Arbeitszeiten)
  • --auto-scheduled-off → sendet explizit null, schaltet sie aus

Der Status der Aufgabe muss die automatische Planung aktiviert haben, sonst lehnt die API ab.

Eine Aufgabenantwort sieht so aus – gekürzt auf die Felder, von denen der Kalender-Workflow unten abhängt:

{
  "id": "tsk_123",
  "name": "Q4-Plan entwerfen",
  "description": "Skizzieren Sie die drei Szenarien.",
  "status": { "name": "In Bearbeitung", "isResolvedStatus": false },
  "priority": "HOCH",
  "labels": ["q4"],
  "assignees": [{ "id": "usr_1", "name": "Sam Patel" }],
  "project": { "id": "prj_1", "name": "Planung" },
  "dueDate": "2026-11-01T17:00:00.000Z",
  "duration": 45,
  "scheduledStart": "2026-10-28T09:00:00.000Z",
  "startOn": "2026-10-28",
  "completedTime": null
}

Lesen Sie es so: status ist ein Objekt, keine Zeichenfolge – der Filter, den Sie möchten, ist status.isResolvedStatus, der true wird, sobald eine Aufgabe abgeschlossen oder abgebrochen ist. assignees und labels sind Arrays; project ist ein Objekt oder null. scheduledStart und dueDate sind UTC; startOn ist ein bloßes Datum.

Es gibt keinen Kalender-Endpunkt. Die Position einer Aufgabe im Kalender ist ihr scheduledStart (UTC ISO 8601), mit duration in Minuten und startOn als einfaches Datum. Um zu beantworten „was kommt als nächstes", rufen Sie die Aufgaben ab und sortieren Sie nach scheduledStart – suchen Sie nicht nach einem Zeitplan- Endpunkt, der Ereignisse zurückgibt, denn schedules list gibt nur die Arbeitszeitenfenster zurück (siehe unten), nicht die gebuchten Elemente. Filtern Sie Aufgaben mit status.isResolvedStatus heraus, um bereits abgeschlossene oder abgebrochene auszuschließen.

Projekte

BefehlEndpunkt
projects list [--workspace-id …]GET /v1/projects
projects get <project_id>GET /v1/projects/{id}
projects create --name … --workspace-id …POST /v1/projects

projects create akzeptiert auch --due-date, --description (HTML akzeptiert), --label (wiederholbar), --priority (Standard ist MITTEL serverseitig) und das Vorlagenpaar --project-definition-id + --stages. Phasen müssen genau mit der Reihenfolge und Anzahl der Definition übereinstimmen, sonst gibt die API 400 zurück. Für lange Phasen-Arrays verwenden Sie --stages @stages.json. Die CLI erzwingt das Paar nicht; die API lehnt eine Phasenliste ohne eine Definitions-ID ab.

Wiederkehrende Aufgaben

BefehlEndpunkt
recurring-tasks list --workspace-id …GET /v1/recurring-tasks
recurring-tasks createPOST /v1/recurring-tasks
recurring-tasks delete <id> --yesDELETE /v1/recurring-tasks/{id}

recurring-tasks create erfordert --frequency, --name, --workspace-id und --assignee-id. Optional: --deadline-type (nur HART/WEICH – KEINE wird hier abgelehnt), --duration (Minuten als ganze Zahl oder ERINNERUNG; KEINE wird an diesem Endpunkt nicht akzeptiert), --starting-on, --ideal-time (HH:mm), --schedule (Standard Arbeitszeiten), --description, --priority (nur HOCH/MITTEL).

--starting-on wird genau wie angegeben an die API gesendet – keine Kürzung.

--frequency ist eine Zeichenfolge in Moutons eigener DSL, kein Objekt. Das bringt Leute durcheinander. Das Vokabular ist dokumentiert unter https://docs.usemotion.com/cookbooks/frequency/:

  • Tagescodes: MO, DI, MI, DO, FR, SA, SO
  • Täglich: daily_every_day, daily_every_week_day, daily_specific_days_[MO, DI, FR]
  • Wöchentlich: weekly_any_day, weekly_any_week_day, weekly_specific_days_[MO, FR]
  • Zweiwöchentlich: biweekly_first_week_any_day, biweekly_first_week_specific_days_[MO, DI], biweekly_second_week_any_week_day
  • Monatlich nach Wochentag: monthly_first_MO, monthly_second_DI, monthly_last_FR
  • Monatlich nach Datum: monthly_1, monthly_15, monthly_31 (ein Tag außerhalb des Bereichs fällt zurück auf den letzten Tag des Monats)
  • Monatlich nach Woche: monthly_any_day_first_week, monthly_any_week_day_last_week, monthly_last_day_of_month
  • Vierteljährlich: quarterly_first_day, quarterly_last_week_day, quarterly_any_day_first_week

Ein Tagesarray muss immer mit einem Häufigkeitstyp gepaart sein – [MO, FR] allein ist nicht gültig.

Ein vollständiger Aufruf, da die Häufigkeitszeichenfolge der schwierige Teil ist:

python3 motion.py recurring-tasks create \
    --name "Wöchentliche Überprüfung" --workspace-id ws_1 --assignee-id usr_1 \
    --frequency "weekly_specific_days_[MO,FR]" \
    --deadline-type WEICH --duration 30 --ideal-time 16:00 \
    --schedule "Arbeitszeiten" --priority MITTEL

Beachten Sie die engeren Mengen hier: Wiederkehrende Aufgaben akzeptieren nur HOCH/MITTEL-Priorität und nur HART/WEICH-Fristtypen, während der Rest der API auch ASAP/NIEDRIG und KEINE zulässt. Die CLI erzwingt beides.

Kommentare

BefehlEndpunkt
comments list --task-id …GET /v1/comments
comments create --task-id … [--content …]POST /v1/comments

--content ist Github Flavored Markdown auf dem Weg hinein und kommt als HTML zurück. Es ist optional – ohne --content trägt der Anforderungstext nur die Aufgaben-ID. Ob Motion einen leeren Kommentar akzeptiert, ist nicht verifiziert; übergeben Sie --content, wenn Sie etwas sagen möchten.

Benutzerdefinierte Felder – beachten Sie das Präfix /beta/

BefehlEndpunkt
custom-fields list --workspace-id …GET /beta/workspaces/{workspaceId}/custom-fields
custom-fields create --workspace-id … --type … --name …POST /beta/workspaces/{workspaceId}/custom-fields
custom-fields delete <id> --workspace-id … --yesDELETE /beta/workspaces/{workspaceId}/custom-fields/{id}
custom-field-values add-task <task_id> …POST /beta/custom-field-values/task/{taskId}
custom-field-values add-project <project_id> …POST /beta/custom-field-values/project/{projectId}
custom-field-values delete-from-task <task_id> <value_id> --yesDELETE /beta/custom-field-values/task/{taskId}/custom-fields/{valueId}
custom-field-values delete-from-project <project_id> <value_id> --yesDELETE /beta/custom-field-values/project/{projectId}/custom-fields/{valueId}

Die 12 benutzerdefinierten Feldtypen, genau wie buchstabiert: text, url, date, person, multiPerson, phone, select, multiSelect, number, email, checkbox, relatedTo.

Das Setzen eines Werts erfordert --custom-field-instance-id (das Feld im Arbeitsbereich), --type, und --value. --value ist JSON, also zitieren Sie es korrekt: --value '"hallo"' für eine Zeichenfolge, --value '42' für eine Zahl, --value '["A","B"]' für eine Mehrfachauswahl, --value 'true' für ein Kontrollkästchen.

python3 motion.py custom-field-values add-task tsk_123 \
    --custom-field-instance-id cfi_1 --type select --value '"Alpha"'

custom-fields create erwartet --metadata als JSON – format (plain/formatted/percent, nur Zahlen), toggle für Kontrollkästchen und options für Auswahlfelder:

--metadata '{"options":[{"id":"a","value":"Alpha","color":"#ff0000"}]}'

Benutzer, Arbeitsbereiche, Status, Zeitpläne

BefehlEndpunkt
meGET /v1/users/me
users list [--workspace-id …] [--team-id …]GET /v1/users
workspaces list [--ids …]GET /v1/workspaces
statuses list [--workspace-id …]GET /v1/statuses
schedules listGET /v1/schedules

workspaces list --ids ist wiederholbar und --all folgt dem Cursor.

users list muss eingegrenzt werden. Übergeben Sie --workspace-id oder --team-id; das Skript weigert sich bei einem uneingeschränkten Aufruf frühzeitig mit dieser Nachricht, anstatt eine Anfrage für den 400 zu verschwenden, den die API zurückgibt. Um alle aufzulisten, durchlaufen Sie Ihre Arbeitsbereiche.

schedules list gibt Arbeitszeitenfenster zurück, keine Ereignisse. Jeder Zeitplan hat seine eigene timezone und ein pro-Tag-Array von {start, end}-Blöcken – und ein Tag kann mehrere Blöcke enthalten (z. B. ein Schulweg-Zeitplan mit einem Morgen- und einem Abendblock). Lesen Sie dies nicht als „Der Benutzer hat einen Arbeitsblock pro Tag" und behandeln Sie es nicht als Kalender; für das, was tatsächlich gebucht ist, lesen Sie die scheduledStart-Werte der Aufgaben.

Raw-Ausweichmöglichkeit

python3 motion.py raw GET  /v1/tasks --query status=Todo --query status=Doing
python3 motion.py raw GET  /v1/tasks --query assigneeId=u1 --query includeAllStatuses=true --all
python3 motion.py raw POST /v1/comments --body '{"taskId":"t1","content":"hi"}'
python3 motion.py raw DELETE /v1/tasks/t1 --yes

Verwenden Sie dies für alles, was die benannten Befehle nicht abdecken. --query KEY=VALUE ist wiederholbar und das Wiederholen des

…

[gekürzt für die Übersetzung]

Verwandte Skills