intermediate
rider-score
appeals
disputes

Appeals and Disputes

How riders file appeals on a score, where the operator handles them in the dashboard, the 7-day SLA, and the full audit trail.

Levy Fleets TeamMay 18, 20268 min read

Appeals and Disputes

Every rider can dispute any trip score and any intervention. The appeal is the user-facing implementation of the GDPR / CCPA right to correction, and it is the relief valve that keeps the scoring system fair.

This article covers what the rider does, what the operator does, the SLA, and the audit trail.

Where Ops handles appeals

Appeals queue: Dashboard > Rider Score > Appeals. Audit log: Dashboard > Rider Score > Audit Log. Both pages are scoped to your subaccount and require operator role permissions to access.

Rider-side flow

  1. On the post-ride breakdown screen, the rider taps Dispute this score.
  2. Alternatively, from an intervention banner ("Throttle cap active for next ride") the rider taps Appeal.
  3. The rider enters a free-text reason and submits.
  4. A score_appeals row is created with status='pending'. If the appeal references a triggering intervention, that intervention flips to status='paused_pending_appeal'.
  5. The rider sees a confirmation screen with the 7-day SLA and the expected response window.

The rider can only file one pending appeal per ride. A partial unique index on score_appeals(ride_uuid) WHERE status='pending' prevents duplicates.

SLA

StatusDefault SLAWhat happens when SLA is missed
pending7 days to first operator actionA reminder is surfaced on the operator dashboard with an SLA warning
resolvedn/aThe rider gets a push notification with the outcome

The 7-day SLA is per-subaccount editable at Settings > Appeals SLA. We do not recommend going lower than 3 days or higher than 14. The rider sees the SLA in-app when they file - that becomes a contract you need to honor.

Operator queue - where Ops actually handles appeals

The operator review surface lives at Dashboard > Rider Score > Appeals. Each row shows:

  • Rider name, customer UUID, total ride count
  • The triggering ride (deep-link to the ride detail page)
  • Per-trip score with the full signal breakdown
  • Rider's free-text reason
  • Linked interventions (if any) - paused while the appeal is pending
  • SLA countdown
  • Actions: Adjust score, Reject appeal, Approve and lift intervention

Side-by-side the rider's reason, the operator sees the ride map, GPS trail, zone events, and throttle frames. This is enough context to decide on most appeals in under a minute.

Operator actions

Adjust the trip score

The most common resolution. The operator picks a new per-trip score (with mandatory reason text), and:

  • ride_safety_signals.trip_score is overridden.
  • The rolling score recomputes downstream.
  • The tier may change.
  • The linked intervention re-evaluates: if the new score no longer crosses the threshold, the intervention closes; otherwise it re-opens at its original step.
  • A score_audit_log row is written with actor user_id, before/after values, and the reason.

Reject the appeal

The operator rejects with a mandatory reason. The intervention re-opens with its original expires_at math. The rider is notified.

Approve and lift the intervention

For appeals where the score is fine but the intervention is not (for example, the rider was helmet-verified but a vendor IoT glitch triggered a throttle cap), the operator can approve the appeal AND lift the intervention without changing the underlying score. A score_audit_log row records the lift with reason.

Required: reason text

Every appeal resolution requires a free-text reason. There is no shortcut button that lets you resolve an appeal without typing a reason. This is enforced server-side. The reason ends up in the audit log and is visible to:

  • Future operators reviewing the same rider
  • A Levy support engineer pulled in on an escalation
  • A subpoenaed record set, if it ever comes to that

Keep reasons specific. "Approved - GPS shows the rider was inside the parking zone but the geofence drew the wrong polygon" is useful. "Approved" is not.

Audit log

Every override, intervention transition, reward issuance, and appeal decision writes to score_audit_log:

ColumnHolds
actor_user_idThe operator who took the action (null for system)
customer_uuidThe affected rider
ride_uuidThe ride (if any)
actionEnum: score_override, intervention_open, intervention_lift, appeal_accepted, appeal_rejected, reward_issued, reward_skipped_cap, etc.
before_jsonbSnapshot of relevant state before
after_jsonbSnapshot after
reasonMandatory free-text
created_atTimestamp

View at Dashboard > Rider Score > Audit Log, filterable by rider, ride, actor, action type, and date range.

What happens while an appeal is pending

  • The linked intervention is paused (status='paused_pending_appeal'). Throttle caps do not apply on the next ride. Temp lockouts do not apply.
  • The rolling score is unchanged.
  • The rider can still ride normally.
  • The intervention's expires_at does NOT tick down during the pause. When the appeal resolves to "rejected," the remaining time-to-expire resumes from where it paused.

What appeals do not do

  • They do not override violations from the Violations module. Violations are appealed in the Violations workflow, not here.
  • They do not refund the rider for a price uplift already charged. Use the standard ride-refund flow if a refund is warranted (see CLAUDE.md - refunds always go against the ride).
  • They do not change the operator-side reward budget. A wallet credit already issued through the refund pipeline is final.

Rental agreement disclosure

Riders cannot meaningfully consent to a scoring system they do not know about. Levy ships the following required language in the rental agreement:

"Levy may reduce vehicle performance for accounts with elevated safety risk profiles. Riders may dispute any trip score or intervention through the in-app appeal flow. Levy responds to appeals within 7 days (or the operator-configured SLA shown in-app at the time of filing)."

If you operate under a custom rental agreement, you need this clause or substantially equivalent language. Ask Levy Sales if you need help with the legal review.

Levy's role

By default, appeals are reviewed by the operator, not by Levy. Levy support can be pulled in on escalations - usually when a rider claims fraud, scoring bias, or a regulatory issue - but the first responder is your ops team.

If your subaccount is paused and there is no available operator, Levy support will handle pending appeals to protect the SLA. This is a fallback, not a default.

Open question

Cross-subaccount appeals (where one rider has scores on multiple operators) are not supported in v1. A rider must file an appeal per operator. v4 considers cross-subaccount appeal aggregation for opt-in power users.


Next

See Intervention Ladder for how appeals interact with each ladder step. See Weights and Settings if a string of appeals points to a weight that needs re-tuning.